मुझे पता है कि सवाल जीसीसी के बारे में है, लेकिन दूसरे और / या कई कंपाइलरों में यह कैसे करना है ...
टी एल; डॉ
आप हेडली पर एक नज़र डालना चाहते हैं , जो एक पब्लिक-डोमेन सिंगल 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_suppress
PGI और 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
हडले को केवल चेतावनी के बारे में पता नहीं है, और न ही सभी हडले चेतावनी दे सकते हैं, लेकिन उम्मीद है कि आपको यह विचार मिलेगा।