Sorunun GCC ile ilgili olduğunu biliyorum, ancak bunu diğer ve / veya çoklu derleyicilerde nasıl yapacağını arayanlar için…
TL; DR
Sizin için bu şeylerin çoğunu yapan bir kamu malı tek C / C ++ başlığı olan Hedley'ye bir göz atmak isteyebilirsiniz . Bu yazının sonunda Hedley'nin tüm bunlar için nasıl kullanılacağı hakkında hızlı bir bölüm koyacağım.
Uyarıyı devre dışı bırakma
#pragma warning (disable: …)
çoğu derleyicide eşdeğerleri vardır:
- MSVC:
#pragma warning(disable:4996)
- GCC:
#pragma GCC diagnostic ignored "-W…"
burada üç nokta uyarının adıdır; örneğin , #pragma GCC diagnostic ignored "-Wdeprecated-declarations
.
- clang:
#pragma clang diagnostic ignored "-W…"
. Sözdizimi temel olarak GCC'lerle aynıdır ve uyarı adlarının çoğu aynıdır (çoğu olmasa da).
- Intel C Derleyici: MSVC sözdizimini kullanın, ancak uyarı numaralarının tamamen farklı olduğunu unutmayın. Örnek:
#pragma warning(disable:1478 1786)
.
- PGI: Bir
diag_suppress
pragma var:#pragma diag_suppress 1215,1444
- TI:
diag_suppress
PGI ile aynı sözdizimine (ancak farklı uyarı numaralarına!) Sahip bir pragma var:pragma diag_suppress 1291,1718
- Oracle Developer Studio (suncc): bir
error_messages
pragma var. Rahatsız edici bir şekilde, C ve C ++ derleyicileri için uyarılar farklıdır. Bunların her ikisi de temelde aynı uyarıları devre dışı bırakır:
- C:
#pragma error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)
- C ++:
#pragma error_messages(off,symdeprecated,symdeprecated2)
- IAR:
diag_suppress
PGI ve TI gibi de kullanır , ancak sözdizimi farklıdır. Uyarı numaralarından bazıları aynı, ancak ben diğerlerinden ayrıldım:#pragma diag_suppress=Pe1444,Pe1215
- Pelles C: MSVC'ye benzer, ancak yine sayılar farklı
#pragma warn(disable:2241)
Çoğu derleyici için, derleyici sürümünü devre dışı bırakmadan önce kontrol etmek genellikle iyi bir fikirdir, aksi takdirde başka bir uyarıyı tetiklersiniz. Örneğin, GCC 7 -Wimplicit-fallthrough
uyarı için destek eklediğinden, 7'den önce GCC'yi önemsiyorsanız, şöyle bir şey yapmalısınız
#if defined(__GNUC__) && (__GNUC__ >= 7)
# pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#endif
Daha yeni XL C / C ++ ve armclang gibi clang tabanlı clang ve derleyiciler için, derleyicinin __has_warning()
makroyu kullanarak belirli bir uyarıyı bilip bilmediğini kontrol edebilirsiniz .
#if __has_warning("-Wimplicit-fallthrough")
# pragma clang diagnostic ignored "-Wimplicit-fallthrough"
#endif
Tabii ki __has_warning()
makronun var olup olmadığını da kontrol etmelisiniz :
#if defined(__has_warning)
# if __has_warning("-Wimplicit-fallthrough")
# pragma clang diagnostic ignored "-Wimplicit-fallthrough"
# endif
#endif
Böyle bir şey yapmaya cazip olabilirsiniz
#if !defined(__has_warning)
# define __has_warning(warning)
#endif
Böylece __has_warning
biraz daha kolay kullanabilirsiniz. Clang, kılavuzlarındaki __has_builtin()
makro için benzer bir şey bile öneriyor . Bunu yapma . Diğer kodlar, __has_warning
derleyici sürümlerini denetleyip denetleyebilir ve eğer tanımlamazsanız __has_warning
, kodlarını kıracaksınız. Bunu yapmanın doğru yolu, ad alanınızda bir makro oluşturmaktır. Örneğin:
#if defined(__has_warning)
# define MY_HAS_WARNING(warning) __has_warning(warning)
#else
# define MY_HAS_WARNING(warning) (0)
#endif
Sonra gibi şeyler yapabilirsiniz
#if MY_HAS_WARNING(warning)
# pragma clang diagnostic ignored "-Wimplicit-fallthrough"
#elif defined(__GNUC__) && (__GNUC__ >= 7)
# pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#endif
İtme ve haşhaş
Birçok derleyici, uyarıları yığının üzerine itme ve açma yolunu da destekler. Örneğin, bu, bir kod satırı için GCC'de bir uyarıyı devre dışı bırakır ve ardından önceki durumuna döndürür:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated"
call_deprecated_function();
#pragma GCC diagnostic pop
Tabii ki derleyiciler arasında sözdizimi hakkında çok fazla anlaşma yok:
- GCC 4.6+:
#pragma GCC diagnostic push
/#pragma GCC diagnostic pop
- clang:
#pragma clang diagnostic push
/#pragma diagnostic pop
- Intel 13+ (ve muhtemelen daha önce):
#pragma warning(push)
/#pragma warning(pop)
- MSVC 15+ (VS 9.0 / 2008):
#pragma warning(push)
/#pragma warning(pop)
- ARM 5.6+:
#pragma push
/#pragma pop
- TI 8.1+:
#pragma diag_push
/#pragma diag_pop
- Pelles C 2.90+ (ve muhtemelen daha önce):
#pragma warning(push)
/#pragma warning(pop)
Bellek hizmet veriyorsa, GCC'nin bazı çok eski sürümleri için (3.x, IIRC gibi) push / pop pragmaları işlevin dışında .
Kanlı ayrıntılarını gizleme
Çoğu derleyici için _Pragma
, C99'da tanıtılan makroların arkasındaki mantığı gizlemek mümkündür . C99 olmayan modda bile, çoğu derleyici destekler _Pragma
; büyük istisna, __pragma
farklı bir sözdizimine sahip kendi anahtar kelimesi olan MSVC'dir. Standart _Pragma
bir dize alır, Microsoft sürümü şunları yapmaz:
#if defined(_MSC_VER)
# define PRAGMA_FOO __pragma(foo)
#else
# define PRAGMA_FOO _Pragma("foo")
#endif
PRAGMA_FOO
Ön işlemden geçirildikten sonra kabaca eşdeğerdir.
#pragma foo
Bu, makrolar oluşturmamızı sağlar, böylece kod yazabiliriz
MY_DIAGNOSTIC_PUSH
MY_DIAGNOSTIC_DISABLE_DEPRECATED
call_deprecated_function();
MY_DIAGNOSTIC_POP
Ve makro tanımlarındaki çirkin sürüm kontrollerini gizleyin.
Kolay yol: Hedley
Artık kodunuzu temiz tutarken böyle şeyleri nasıl taşınabilir yapmanın mekaniğini anladığınıza göre, projelerimden biri olan Hedley'nin ne yaptığını anlıyorsunuz . Tonlarca belgeyi incelemek ve / veya test edebildiğiniz kadar çok derleyicinin birçok sürümünü yüklemek yerine, Hedley'yi (tek bir kamu malı C / C ++ başlığıdır) dahil edebilir ve onunla yapabilirsiniz. Örneğin:
#include "hedley.h"
HEDLEY_DIAGNOSTIC_PUSH
HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
call_deprecated();
HEDLEY_DIAGNOSTIC_POP
GCC, clang, ICC, PGI, MSVC, TI, IAR, ODS, Pelles ve muhtemelen diğerlerinde kullanımdan kaldırılmış bir işlevi çağırmayla ilgili uyarıyı devre dışı bırakacaktır (Hedley'i güncellerken muhtemelen bu cevabı güncellemekten rahatsız olmayacağım). Ayrıca, çalışması bilinmeyen derleyicilerde, makrolar hiçbir şeye önceden işlenmeyecektir, bu nedenle kodunuz herhangi bir derleyici ile çalışmaya devam edecektir. Elbette HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
Hedley'in bildiği tek uyarı değildir ve tüm Hedley'in yapabileceği uyarıları devre dışı bırakmaz, ancak umarım bu fikri anlarsınız.