कोड की कुछ पंक्तियों के लिए GCC चेतावनियों को निष्क्रिय कैसे करें


220

दृश्य C ++ में, इसका उपयोग करना संभव है #pragma warning (disable: ...)। इसके अलावा मैंने पाया कि जीसीसी में आप प्रति फ़ाइल संकलक झंडे को ओवरराइड कर सकते हैं । मैं "अगली पंक्ति" के लिए यह कैसे कर सकता हूं, या जीसीसी का उपयोग करके कोड के क्षेत्रों के आसपास पुश / पॉप शब्दार्थ के साथ?


1
gcc - Oops में अक्षम विशिष्ट चेतावनियों के संभावित डुप्लिकेट , वास्तव में यह सवाल ही एक डुबकी है (लेकिन बंद नहीं)। वह सिर्फ वही होता है जो "संबंधित" के तहत दिखाया जाता है। वैसे भी, यह SO पर कई बार पूछा और उत्तर दिया गया है।
टायलर मैकहेनरी

1
@paxdiablo: मैं उल्टा काम कर रहा हूँ। मैंने चेतावनी स्तर को बहुत ऊपर उठा दिया है, और चेतावनी रेखा को स्क्वाश करना चाहता हूं जिसे मैंने ठीक होने के लिए सत्यापित किया है।
मैट जॉइनर

4
@ टायलर मैकहेनरी: यदि आपने अधिक ध्यान से जाँच की है तो आप ध्यान दे सकते हैं कि लिंक किए गए प्रश्न में प्रति-फ़ाइल समाधान शामिल है, ठीक उसी तरह जिसका मैंने अपने प्रश्न में उल्लेख किया था असंतोषजनक (मैंने लिंक को चुरा लिया है)।
मैट जॉइनर

6
@ paxdiablo, कंपाइलर झूठी सकारात्मकता देते हैं, कभी-कभी आप -Werror के साथ संकलन करना चाहते हैं, लेकिन इन झूठे सकारात्मकों को एक बिल्ड ब्लॉक नहीं करते हैं। इसलिए घटिया मामलों को अक्षम करना और टिप्पणी करना क्यों - कुछ मामलों में समझ में आता है। ऐसे अन्य मामले भी हैं जहां यह काम किया जा सकता है - जैसे ऑटो-जनरेटिंग कोड जो हानिरहित चेतावनी उत्पन्न करता है जो कि अंदर जाना और बदलना (कोड उत्पन्न होने के बाद) के लिए इतना आसान नहीं है, हालांकि उस मामले में प्रति फ़ाइल को अक्षम करने की संभावना अधिक है समाधान।
सुविचार 4242

जवाबों:


221

ऐसा प्रतीत होता है कि यह किया जा सकता है । मैं जीसीसी के संस्करण को निर्धारित करने में असमर्थ हूं कि इसे जोड़ा गया था, लेकिन यह जून 2010 से कुछ समय पहले था।

यहाँ एक उदाहरण है:

#pragma GCC diagnostic error "-Wuninitialized"
    foo(a);         /* error is given for this one */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuninitialized"
    foo(b);         /* no diagnostic for this one */
#pragma GCC diagnostic pop
    foo(c);         /* error is given for this one */
#pragma GCC diagnostic pop
    foo(d);         /* depends on command line options */

14
एक pushऔर दो popएस - pushशुरुआत में एक और गायब हो सकता है?
abyss.7

37
# अर्गमा जीसीसी डायग्नोस्टिक पुश #pragma GCC डायग्नोस्टिक पॉप कारण GCC को प्रत्येक पुश के रूप में डायग्नोस्टिक्स की स्थिति को याद रखने के लिए, और प्रत्येक पॉप पर उस बिंदु पर पुनर्स्थापित करें। यदि किसी पॉप में कोई मेल नहीं खाता है, तो कमांड-लाइन विकल्प बहाल होते हैं। " - जीसीसी मैनुअल से: gcc.gnu.org/oniltocs/gcc/Diagnostic-Pragmas.html
bobpaul

11
संदर्भ के लिए, gcc संस्करण 4.4.3 त्रुटि / चेतावनी / अनदेखी का समर्थन करता है, लेकिन पुश / पॉप
फ़्रैंकस्टर नहीं

12
जीसीसी का पहला संस्करण जिसमें डायग्नोस्टिक पुश / पॉप था, जीसीसी 4.6.4 है । मैंने GCC डॉक्यूमेंटेशन
bitek

5
इसकी शर्म की बात यह अभ्यास में काम नहीं करता है। कुछ मामलों में, यह अधिक चेतावनी पैदा करता है। या हो सकता है, अधिक सही ढंग से, यह 5.1 के माध्यम से जीसीसी 4.7 के लिए अभ्यास में काम नहीं करता है। उदाहरण के लिए, जीसीसी मौन चेतावनियों के लिए 'प्रज्ञा जीसीसी डायग्नोस्टिक' का सम्मान नहीं करता है
jww

108

सब कुछ शुद्ध करने के लिए, यह अस्थायी रूप से चेतावनी को अक्षम करने का एक उदाहरण है :

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-result"
    write(foo, bar, baz);
#pragma GCC diagnostic pop

आप जांच कर सकते हैं अधिक विवरण के लिए नैदानिक ​​pragmas पर जीसीसी प्रलेखन की


2
काम करना चाहिए, लेकिन मेरी gcc-4.9बस इस लाइन को पूरी तरह से नजरअंदाज कर देती है।
अलेक्सी पेट्रेंको

31

TL; DR : यदि यह काम करता है, तो बचें, या जैसे स्पेसर का उपयोग करें __attribute__, अन्यथा_Pragma

यह जीसीसी और क्लैंग में मेरे ब्लॉग लेख सप्रेसिंग चेतावनियों का एक छोटा संस्करण है

निम्नलिखित को धयान मे रखते हुए Makefile

CPPFLAGS:=-std=c11 -W -Wall -pedantic -Werror

.PHONY: all
all: puts

निम्नलिखित puts.cस्रोत कोड के निर्माण के लिए

#include <stdio.h>

int main(int argc, const char *argv[])
{
    while (*++argv) puts(*argv);
    return 0;
}

यह argcअप्रयुक्त नहीं होगा क्योंकि अप्रयुक्त है, और सेटिंग्स कट्टर हैं (-W -Wall -pedantic -Werror ) हैं।

5 चीजें हैं जो आप कर सकते हैं:

  • यदि संभव हो तो सोर्स कोड में सुधार करें
  • एक घोषणा विनिर्देश का उपयोग करें, जैसे __attribute__
  • उपयोग _Pragma
  • उपयोग #pragma
  • कमांड लाइन विकल्प का उपयोग करें।

स्रोत में सुधार

चेतावनी से छुटकारा पाने के लिए स्रोत कोड में सुधार किया जा सकता है, तो पहले प्रयास की जाँच होनी चाहिए। इस मामले में हम एल्गोरिथ्म को सिर्फ इसलिए बदलना नहीं चाहते हैं, जैसा कि ( अंतिम तत्व के बाद) argcबेमानी है ।!*argvNULL

घोषणा स्पेसिफायर का उपयोग करना, जैसे __attribute__

#include <stdio.h>

int main(__attribute__((unused)) int argc, const char *argv[])
{
    while (*++argv) puts(*argv);
    return 0;
}

यदि आप भाग्यशाली हैं, तो मानक आपकी स्थिति के लिए एक विनिर्देशक प्रदान करता है, जैसे _Noreturn

__attribute__मालिकाना जीसीसी विस्तार (क्लैंग द्वारा समर्थित और armccसाथ ही कुछ अन्य संकलक ) और कई अन्य संकलक द्वारा नहीं समझा जाएगा। __attribute__((unused))यदि आप पोर्टेबल कोड चाहते हैं तो मैक्रो के अंदर रखें ।

_Pragma ऑपरेटर

_Pragmaके विकल्प के रूप में इस्तेमाल किया जा सकता है #pragma

#include <stdio.h>

_Pragma("GCC diagnostic push")
_Pragma("GCC diagnostic ignored \"-Wunused-parameter\"")

int main(int argc, const char *argv[])
{
    while (*++argv) puts(*argv);
    return 0;
}
_Pragma("GCC diagnostic pop")

_Pragmaऑपरेटर का मुख्य लाभ यह है कि आप इसे मैक्रोज़ के अंदर रख सकते हैं, जो #pragmaनिर्देश के साथ संभव नहीं है ।

डाउनसाइड: यह लगभग एक सामरिक परमाणु है, क्योंकि यह घोषणा-आधारित के बजाय लाइन-आधारित काम करता है।

_Pragmaऑपरेटर C99 में पेश किया गया था।

#pragma निर्देश।

हम कोड के एक क्षेत्र के लिए चेतावनी को दबाने के लिए स्रोत कोड को बदल सकते हैं, आमतौर पर एक संपूर्ण कार्य:

#include <stdio.h>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
int main(int argc, const char *argv[])
{
    while (*++argc) puts(*argv);
    return 0;
}
#pragma GCC diagnostic pop

डाउनसाइड: यह लगभग एक सामरिक परमाणु है, क्योंकि यह घोषणा-आधारित के बजाय लाइन-आधारित काम करता है।

ध्यान दें कि एक समान वाक्यविन्यास क्लैंग में मौजूद है ।

एकल फ़ाइल के लिए कमांड लाइन पर चेतावनी को दबाने

हम Makefileविशेष रूप से पुट के लिए चेतावनी को दबाने के लिए निम्नलिखित पंक्ति जोड़ सकते हैं :

CPPFLAGS:=-std=c11 -W -Wall -pedantic -Werror

.PHONY: all
all: puts

puts.o: CPPFLAGS+=-Wno-unused-parameter

यह शायद आप अपने विशेष मामले में नहीं चाहते हैं, लेकिन यह अन्य रीड्स की मदद कर सकता है जो समान स्थितियों में हैं।


2
पुन: improving the sourceयह int main(int, const char* argv[]) { ... }तर्क को एक नाम न देकर मुख्य की घोषणा को बदलने के लिए भी काम करेगा , आप संकलक को बताएं कि यह अप्रयुक्त होगा।
जेसी चिशोल्म

1
@JesseChisholm फ़ंक्शन परिभाषा में पैरामीटर नाम को छोड़ना संभव नहीं है। आईएसओ / IEC9899 की 6.9.1 समारोह definintions देखें, §5 और सही ढंग से तो कोड द्वारा अस्वीकृत कर दिया जाएगा "declarator एक पैरामीटर प्रकार सूची में शामिल हैं, तो प्रत्येक पैरामीटर की घोषणा एक पहचानकर्ता [...] शामिल होगा" gccके साथ-साथ clang
ईसाई हुजेर

1
एक और पैटर्न सिर्फ वैरिएबल की एक कास्ट को शून्य करना है। वास्तव में, मैंने एक परियोजना में निम्नलिखित मैक्रो को देखा है: #define UNUSED(x) ((void)x)चेतावनियों को चुप करने के लिए उपयोग किया जाता है। मुझे लगता है कि यह रिएक्टोस में था?
पॉल स्टेलियन

1
मुझे नहीं लगता कि आपको इसके बाद बैकस्लैश की जरूरत है, नहीं? _Pragma("GCC diagnostic pop") \ बस _Pragma("GCC diagnostic pop")मुझे सोचना चाहिए ।
गेब्रियल स्टेपल्स

1
@GabrielStaples यह सही है, ध्यान देने के लिए धन्यवाद, मैंने जवाब अपडेट कर दिया है।
क्रिश्चियन हुजर

20
#define DIAG_STR(s) #s
#define DIAG_JOINSTR(x,y) DIAG_STR(x ## y)
#ifdef _MSC_VER
#define DIAG_DO_PRAGMA(x) __pragma (#x)
#define DIAG_PRAGMA(compiler,x) DIAG_DO_PRAGMA(warning(x))
#else
#define DIAG_DO_PRAGMA(x) _Pragma (#x)
#define DIAG_PRAGMA(compiler,x) DIAG_DO_PRAGMA(compiler diagnostic x)
#endif
#if defined(__clang__)
# define DISABLE_WARNING(gcc_unused,clang_option,msvc_unused) DIAG_PRAGMA(clang,push) DIAG_PRAGMA(clang,ignored DIAG_JOINSTR(-W,clang_option))
# define ENABLE_WARNING(gcc_unused,clang_option,msvc_unused) DIAG_PRAGMA(clang,pop)
#elif defined(_MSC_VER)
# define DISABLE_WARNING(gcc_unused,clang_unused,msvc_errorcode) DIAG_PRAGMA(msvc,push) DIAG_DO_PRAGMA(warning(disable:##msvc_errorcode))
# define ENABLE_WARNING(gcc_unused,clang_unused,msvc_errorcode) DIAG_PRAGMA(msvc,pop)
#elif defined(__GNUC__)
#if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406
# define DISABLE_WARNING(gcc_option,clang_unused,msvc_unused) DIAG_PRAGMA(GCC,push) DIAG_PRAGMA(GCC,ignored DIAG_JOINSTR(-W,gcc_option))
# define ENABLE_WARNING(gcc_option,clang_unused,msvc_unused) DIAG_PRAGMA(GCC,pop)
#else
# define DISABLE_WARNING(gcc_option,clang_unused,msvc_unused) DIAG_PRAGMA(GCC,ignored DIAG_JOINSTR(-W,gcc_option))
# define ENABLE_WARNING(gcc_option,clang_option,msvc_unused) DIAG_PRAGMA(GCC,warning DIAG_JOINSTR(-W,gcc_option))
#endif
#endif

यह gcc, clang और msvc के लिए ट्रिक करना चाहिए

जैसे के साथ बुलाया जा सकता है:

DISABLE_WARNING(unused-variable,unused-variable,42)
[.... some code with warnings in here ....]
ENABLE_WARNING(unused-variable,unused-variable,42)

देख https://gcc.gnu.org/onlinedocs/cpp/Pragmas.html , http://clang.llvm.org/docs/UsersManual.html#controlling-diagnostics-via-pragmas और https://msdn.microsoft अधिक जानकारी के लिए .com / de-DE / पुस्तकालय / d9x1s805.aspx

आपको कम से कम संस्करण 4.02 की आवश्यकता है gcc के लिए इस तरह के प्रचार का उपयोग करने के लिए, msvc के बारे में निश्चित नहीं है और संस्करणों के बारे में क्लैंग करें।

ऐसा लगता है कि gcc के लिए पुश पॉप प्रैगमा हैंडलिंग थोड़ा टूट गया है। यदि आप चेतावनी को फिर से सक्षम करते हैं, तो आपको अभी भी उस ब्लॉक के लिए चेतावनी मिलती है जो DISABLE_WARNING / ENABLE_WARNING ब्लॉक के अंदर था। जीसीसी के कुछ संस्करणों के लिए यह काम करता है, कुछ के लिए यह नहीं है।


3
आप असली MVP
zeboidlund

19
#pragma GCC diagnostic ignored "-Wformat"

अपने चेतावनी ध्वज के नाम के साथ "-फॉर्मट" बदलें।

AFAIK इस विकल्प के लिए पुश / पॉप शब्दार्थ का उपयोग करने का कोई तरीका नहीं है।


4
इसकी शर्म की बात यह अभ्यास में काम नहीं करता है। कुछ मामलों में, यह अधिक चेतावनी पैदा करता है। या हो सकता है, अधिक सही ढंग से, यह 5.1 के माध्यम से जीसीसी 4.7 के लिए अभ्यास में काम नहीं करता है। उदाहरण के लिए, जीसीसी मौन चेतावनी के लिए 'प्रज्ञा जीसीसी डायग्नोस्टिक' का सम्मान नहीं करता है
jww

6

आरओएस हेडर जैसे बाहरी पुस्तकालयों के साथ मेरे पास एक ही मुद्दा था। मैं कड़े संकलन के लिए CMakeLists.txt में निम्नलिखित विकल्पों का उपयोग करना पसंद करता हूं:

set(CMAKE_CXX_FLAGS "-std=c++0x -Wall -Wextra -Wstrict-aliasing -pedantic -Werror -Wunreachable-code ${CMAKE_CXX_FLAGS}")

हालाँकि ऐसा करने से बाहरी रूप से शामिल पुस्तकालयों में सभी प्रकार की पांडित्य संबंधी त्रुटियाँ हो जाती हैं। बाहरी पुस्तकालयों को शामिल करने और इस तरह से पुन: सक्षम करने से पहले समाधान सभी पांडित्य चेतावनी को अक्षम करना है:

//save compiler switches
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"

//Bad headers with problem goes here
#include <ros/ros.h>
#include <sensor_msgs/LaserScan.h>

//restore compiler switches
#pragma GCC diagnostic pop

2
क्या इसे बेहतर तरीके से gcc के सिस्टम डाइरेक्टरीज़ के साथ नहीं संभाला जाना चाहिए ?
रेड XIII

@RedXIII - हां, यह एक विकल्प है यदि आप ऐसी निर्देशिकाओं की सूची बना सकते हैं और gcc कमांड लाइन में निर्दिष्ट कर सकते हैं। हालाँकि कई बार कंपाइलर को पाइप लाइन में गहराई तक घुसना पड़ता है या आपको इस बात पर ज्यादा नियंत्रण नहीं होता है कि किसी और को आपके कोड को कैसे संकलित करना चाहिए। ऊपर उन मामलों में शायद एक बेहतर समाधान है।
शीतल शाह

5

मुझे पता है कि सवाल जीसीसी के बारे में है, लेकिन दूसरे और / या कई कंपाइलरों में यह कैसे करना है ...

टी एल; डॉ

आप हेडली पर एक नज़र डालना चाहते हैं , जो एक पब्लिक-डोमेन सिंगल C / C ++ हैडर है जो मैंने लिखा है जो बहुत कुछ करता है आपके लिए इस सामान का । मैं इस पोस्ट के अंत में इस सब के लिए हडले का उपयोग करने के बारे में एक त्वरित अनुभाग डालूँगा।

चेतावनी को अक्षम करना

#pragma warning (disable: …) अधिकांश संकलक में समतुल्य है:

  • MSVC: #pragma warning(disable:4996)
  • जीसीसी: #pragma GCC diagnostic ignored "-W…"जहां दीर्घवृत्त चेतावनी का नाम है; जैसे , #pragma GCC diagnostic ignored "-Wdeprecated-declarations
  • बजना: #pragma clang diagnostic ignored "-W…"। सिंटैक्स मूल रूप से जीसीसी के समान है, और चेतावनी के कई नाम समान हैं (हालांकि कई नहीं हैं)।
  • इंटेल सी कंपाइलर: MSVC सिंटैक्स का उपयोग करें, लेकिन ध्यान रखें कि चेतावनी संख्या पूरी तरह से अलग हैं। उदाहरण: #pragma warning(disable:1478 1786)
  • पीजीआई: एक diag_suppressप्रगति है:#pragma diag_suppress 1215,1444
  • TI: वहाँ एक है diag_suppress PGI के रूप में एक ही वाक्यविन्यास (लेकिन अलग-अलग चेतावनी संख्या!) के साथ एक प्रज्ञा है:pragma diag_suppress 1291,1718
  • Oracle डेवलपर Studio (suncc): एक प्राग है error_messages। आमतौर पर, चेतावनियाँ C और C ++ कंपाइलर के लिए अलग-अलग होती हैं। ये दोनों मूल रूप से एक ही चेतावनी को अक्षम करते हैं:
    • सी: #pragma error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)
    • सी ++: #pragma error_messages(off,symdeprecated,symdeprecated2)
  • IAR: diag_suppressPGI और TI की तरह भी उपयोग करता है , लेकिन वाक्यविन्यास अलग है। कुछ चेतावनी संख्याएँ समान हैं, लेकिन मैंने दूसरों को अलग कर दिया है:#pragma diag_suppress=Pe1444,Pe1215
  • Pelles C: MSVC के समान, हालांकि फिर से संख्या भिन्न होती है #pragma warn(disable:2241)

अधिकांश संकलक के लिए यह संकलक को अक्षम करने का प्रयास करने से पहले संकलक संस्करण की जांच करना अक्सर एक अच्छा विचार है, अन्यथा आप बस एक और चेतावनी को ट्रिगर करेंगे। उदाहरण के लिए, जीसीसी 7 ने -Wimplicit-fallthroughचेतावनी के लिए समर्थन जोड़ा , इसलिए यदि आप 7 से पहले जीसीसी के बारे में परवाह करते हैं तो आपको कुछ ऐसा करना चाहिए

#if defined(__GNUC__) && (__GNUC__ >= 7)
#  pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#endif

क्लेंग और क्लेयर्स के आधार पर क्लेंग के आधार पर जैसे कि XL C / C ++ और आर्मक्लैंग के नए संस्करण, आप देख सकते हैं कि कंपाइलर __has_warning()मैक्रो का उपयोग करके किसी विशेष चेतावनी के बारे में जानता है या नहीं ।

#if __has_warning("-Wimplicit-fallthrough")
#  pragma clang diagnostic ignored "-Wimplicit-fallthrough"
#endif

बेशक आपको यह देखना होगा कि क्या __has_warning()मैक्रो मौजूद है:

#if defined(__has_warning)
#  if __has_warning("-Wimplicit-fallthrough")
#    pragma clang diagnostic ignored "-Wimplicit-fallthrough"
#  endif
#endif

आपको कुछ ऐसा करने के लिए लुभाया जा सकता है

#if !defined(__has_warning)
#  define __has_warning(warning)
#endif

इसलिए आप __has_warningथोड़ा और आसानी से उपयोग कर सकते हैं। क्लैंग भी __has_builtin()अपने मैनुअल में मैक्रो के लिए कुछ इसी तरह का सुझाव देते हैं । यह मत करो । अन्य कोड के लिए जाँच कर सकते हैं __has_warningऔर संकलक संस्करणों पर वापस गिर अगर यह मौजूद नहीं है, और यदि आप परिभाषित __has_warningकरते हैं कि आप उनके कोड को तोड़ देंगे। ऐसा करने का सही तरीका है कि आप अपने नामस्थान में एक मैक्रो बनाएं। उदाहरण के लिए:

#if defined(__has_warning)
#  define MY_HAS_WARNING(warning) __has_warning(warning)
#else
#  define MY_HAS_WARNING(warning) (0)
#endif

फिर आप सामान की तरह कर सकते हैं

#if MY_HAS_WARNING(warning)
#  pragma clang diagnostic ignored "-Wimplicit-fallthrough"
#elif defined(__GNUC__) && (__GNUC__ >= 7)
#  pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#endif

धक्का और पॉपिंग

कई कंपाइलर एक स्टैक पर पुश और पॉप चेतावनियों का भी समर्थन करते हैं। उदाहरण के लिए, यह कोड की एक पंक्ति के लिए GCC पर एक चेतावनी को अक्षम कर देगा, फिर इसे अपनी पिछली स्थिति में लौटा देगा:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated"
call_deprecated_function();
#pragma GCC diagnostic pop

बेशक सिंटैक्स के बारे में कंपाइलरों में बहुत अधिक समझौता नहीं है:

  • जीसीसी 4.6+: #pragma GCC diagnostic push/#pragma GCC diagnostic pop
  • क्लैंग: #pragma clang diagnostic push/#pragma diagnostic pop
  • इंटेल 13+ (और शायद पहले): #pragma warning(push)/#pragma warning(pop)
  • MSVC 15+ (VS 9.0 / 2008): #pragma warning(push)/#pragma warning(pop)
  • एआरएम 5.6+: #pragma push/#pragma pop
  • TI 8.1+: #pragma diag_push/#pragma diag_pop
  • पेलेस सी 2.90+ (और शायद पहले): #pragma warning(push)/#pragma warning(pop)

यदि मेमोरी कार्य करती है, तो जीसीसी के कुछ बहुत पुराने संस्करणों (जैसे 3.x, IIRC) को कार्य के बाहर पुश / पॉप प्रैग्मस होना चाहिए ।

गैरी विवरण छिपा रहा है

अधिकांश कंपाइलरों के लिए मैक्रोज़ के पीछे के तर्क को छिपाना संभव है _Pragma, जिसे C99 में पेश किया गया था। गैर-सी 99 मोड में भी, अधिकांश कंपाइलर समर्थन करते हैं _Pragma; बड़ा अपवाद MSVC है, जिसका अपना __pragmaएक अलग सिंटैक्स वाला कीवर्ड है। मानक _Pragmaएक स्ट्रिंग लेता है, Microsoft का संस्करण नहीं है:

#if defined(_MSC_VER)
#  define PRAGMA_FOO __pragma(foo)
#else
#  define PRAGMA_FOO _Pragma("foo")
#endif
PRAGMA_FOO

मोटे तौर पर समतुल्य है, एक बार पूर्वप्रक्रमित, को

#pragma foo

इससे हम मैक्रोज़ बना सकते हैं ताकि हम जैसे कोड लिख सकें

MY_DIAGNOSTIC_PUSH
MY_DIAGNOSTIC_DISABLE_DEPRECATED
call_deprecated_function();
MY_DIAGNOSTIC_POP

और मैक्रो परिभाषाओं में सभी बदसूरत संस्करण की जांच को छिपाएं।

आसान तरीका: हेडली

अब जब आप अपने कोड को साफ रखने के दौरान मैकेनिकली इस तरह से सामान को किस तरह से करना चाहते हैं, आप समझते हैं, तो आप समझते हैं कि मेरा एक प्रोजेक्ट, हेडली क्या करता है। टंकण के माध्यम से खुदाई करने और / या कई संकलक के कई संस्करणों को स्थापित करने के बजाय, जिसके साथ आप परीक्षण कर सकते हैं, आप बस हडले को शामिल कर सकते हैं (यह एक एकल सार्वजनिक डोमेन C / C ++ हैडर है) और इसके साथ किया जा सकता है। उदाहरण के लिए:

#include "hedley.h"

HEDLEY_DIAGNOSTIC_PUSH
HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
call_deprecated();
HEDLEY_DIAGNOSTIC_POP

जीसीसी, क्लैंग, आईसीसी, पीजीआई, एमएसवीसी, टीआई, आईएआर, ओडीएस, पेल्स, और संभवतः अन्य पर एक पदावनत समारोह को बुलाने के बारे में चेतावनी को अक्षम कर देगा (संभवतः मैं इस अपडेट को अपडेट करने में परेशान नहीं करूंगा क्योंकि मैं हेडली को अपडेट करता हूं)। और, संकलक जो काम करने के लिए नहीं जाने जाते हैं, उन पर मैक्रोज़ को कुछ भी नहीं के लिए प्रीप्रोसेस किया जाएगा, इसलिए आपका कोड किसी भी संकलक के साथ काम करना जारी रखेगा। बेशक HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATEDहडले को केवल चेतावनी के बारे में पता नहीं है, और न ही सभी हडले चेतावनी दे सकते हैं, लेकिन उम्मीद है कि आपको यह विचार मिलेगा।


3

चेतावनियों को चुप कराने के बजाय, जीसीसी शैली आमतौर पर मानक सी कंस्ट्रक्शंस का उपयोग करने के लिए होती है या __attribute__संकलक को उनके इरादे के बारे में अधिक बताने के लिए होती है। उदाहरण के लिए, एक शर्त के रूप में उपयोग किए जाने वाले असाइनमेंट के बारे में चेतावनी को कोष्ठक में असाइनमेंट डाल दिया जाता है, अर्थात if ((p=malloc(cnt)))इसके बजाय if (p=malloc(cnt))। अप्रयुक्त फ़ंक्शन तर्कों के बारे में चेतावनियों को कुछ अजीब से दबाया जा सकता है जिन्हें __attribute__मैं कभी भी याद नहीं कर सकता, या स्व-असाइनमेंट आदि के द्वारा, लेकिन आम तौर पर मैं किसी भी चेतावनी विकल्प को अक्षम करना पसंद करता हूं जो सही कोड में होने वाली चीजों के लिए चेतावनी उत्पन्न करता है।


2
संभावित हो। मेरा इरादा किसी भी सामान्य मामले के पैटर्न को साबित करना नहीं है, बल्कि चेतावनी दमन पर gcc का दर्शन क्या है, इसके बारे में अवलोकन है।
आर .. गिटहब स्टॉप हेल्पिंग आईसीई जूल

संकलक अलग-अलग w / r / t चेतावनियों को अतिरिक्त कोष्ठक के साथ व्यवहार करता है?!?!? !!!! वाह! यह अप्रत्याशित है।
जेसन एस

1
@ जोंस ने कंपाइलर के व्यवहार की चेतावनी को बदल नहीं दिया है, जो वह करता है वह बयान के शब्दार्थ को बदल देता है। अतिरिक्त परेंसर्स कंपाइलर का काम पूरा करते हैं और एक अभिव्यक्ति के रूप में इसका अंतिम मूल्य रखते हैं, जो बिना किसी चेतावनी के योग्य है। यदि आप स्पष्टता चाहते हैं, तो आप कह सकते हैं if ((p=malloc(cnt)) != NULL) ...कि कंपाइलर पर्दे के पीछे क्या कर रहा है।
जेसी चिशोल्म

@ जेसे शीशमोल: मुझे नहीं लगता कि आपकी व्याख्या सटीक है।
R .. गिटहब स्टॉप हेल्पिंग ICE

3

जिन लोगों को यह पृष्ठ IAR में ऐसा करने का तरीका मिल रहा है, उनके लिए यह प्रयास करें:

#pragma diag_suppress=Pe177
void foo1( void )
{
   /* The following line of code would normally provoke diagnostic 
      message #177-D: variable "x" was declared but never referenced.
      Instead, we have suppressed this warning throughout the entire 
      scope of foo1(). 
   */
   int x;
}
#pragma diag_default=Pe177

संदर्भ के लिए http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0472m/chr1359124244797.html देखें ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.