Saya tahu pertanyaannya adalah tentang GCC, tetapi untuk orang yang mencari cara melakukan ini di kompiler lain dan / atau banyak ...
TL; DR
Anda mungkin ingin melihat Hedley , yang merupakan header domain publik C / C ++ tunggal yang saya tulis yang memberikan banyak hal untuk Anda. Saya akan memasukkan bagian singkat tentang cara menggunakan Hedley untuk semua ini di akhir posting ini.
Menonaktifkan peringatan
#pragma warning (disable: …)
memiliki padanan dalam kebanyakan kompiler:
- MSVC:
#pragma warning(disable:4996)
- GCC: di
#pragma GCC diagnostic ignored "-W…"
mana elipsis adalah nama peringatan; misalnya , #pragma GCC diagnostic ignored "-Wdeprecated-declarations
.
- dentang:
#pragma clang diagnostic ignored "-W…"
. Sintaksisnya pada dasarnya sama dengan GCC, dan banyak dari nama peringatan itu sama (walaupun banyak yang tidak).
- Intel C Compiler: Gunakan sintaks MSVC, tetapi perlu diingat bahwa nomor peringatan sama sekali berbeda. Contoh:
#pragma warning(disable:1478 1786)
.
- PGI: Ada
diag_suppress
pragma:#pragma diag_suppress 1215,1444
- TI: Ada
diag_suppress
pragma dengan sintaks yang sama (tetapi nomor peringatan berbeda!) Dengan PGI:pragma diag_suppress 1291,1718
- Oracle Developer Studio (suncc): ada
error_messages
pragma. Mengganggu, peringatan berbeda untuk kompiler C dan C ++. Kedua menonaktifkan ini pada dasarnya peringatan yang sama:
- C:
#pragma error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)
- C ++:
#pragma error_messages(off,symdeprecated,symdeprecated2)
- IAR: juga menggunakan
diag_suppress
seperti PGI dan TI, tetapi sintaksnya berbeda. Beberapa nomor peringatannya sama, tetapi saya yang lain telah menyimpang:#pragma diag_suppress=Pe1444,Pe1215
- Pelles C: mirip dengan MSVC, meskipun sekali lagi angkanya berbeda
#pragma warn(disable:2241)
Untuk sebagian besar kompiler, sebaiknya memeriksa versi kompiler sebelum menonaktifkannya, jika tidak, Anda hanya akan memicu peringatan lain. Misalnya, GCC 7 menambahkan dukungan untuk -Wimplicit-fallthrough
peringatan, jadi jika Anda peduli dengan GCC sebelum 7, Anda harus melakukan sesuatu seperti
#if defined(__GNUC__) && (__GNUC__ >= 7)
# pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#endif
Untuk dentang dan kompiler yang didasarkan pada dentang seperti versi yang lebih baru dari XL C / C ++ dan armclang, Anda dapat memeriksa untuk melihat apakah kompiler tahu tentang peringatan tertentu menggunakan __has_warning()
makro.
#if __has_warning("-Wimplicit-fallthrough")
# pragma clang diagnostic ignored "-Wimplicit-fallthrough"
#endif
Tentu saja Anda juga harus memeriksa untuk melihat apakah __has_warning()
makro ada:
#if defined(__has_warning)
# if __has_warning("-Wimplicit-fallthrough")
# pragma clang diagnostic ignored "-Wimplicit-fallthrough"
# endif
#endif
Anda mungkin tergoda untuk melakukan sesuatu seperti
#if !defined(__has_warning)
# define __has_warning(warning)
#endif
Jadi Anda bisa menggunakan __has_warning
sedikit lebih mudah. Dentang bahkan menyarankan sesuatu yang mirip dengan __has_builtin()
makro di manual mereka. Jangan lakukan ini . Kode lain mungkin memeriksa __has_warning
dan kembali memeriksa versi kompiler jika tidak ada, dan jika Anda menentukan __has_warning
Anda akan memecahkan kode mereka. Cara yang tepat untuk melakukan ini adalah membuat makro di namespace Anda. Sebagai contoh:
#if defined(__has_warning)
# define MY_HAS_WARNING(warning) __has_warning(warning)
#else
# define MY_HAS_WARNING(warning) (0)
#endif
Maka Anda dapat melakukan hal-hal seperti
#if MY_HAS_WARNING(warning)
# pragma clang diagnostic ignored "-Wimplicit-fallthrough"
#elif defined(__GNUC__) && (__GNUC__ >= 7)
# pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#endif
Mendorong dan bermunculan
Banyak kompiler juga mendukung cara untuk mendorong dan mengeluarkan peringatan ke tumpukan. Misalnya, ini akan menonaktifkan peringatan pada GCC untuk satu baris kode, lalu mengembalikannya ke status sebelumnya:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated"
call_deprecated_function();
#pragma GCC diagnostic pop
Tentu saja tidak ada banyak kesepakatan di antara kompiler tentang sintaks:
- GCC 4.6+:
#pragma GCC diagnostic push
/#pragma GCC diagnostic pop
- dentang:
#pragma clang diagnostic push
/#pragma diagnostic pop
- Intel 13+ (dan mungkin sebelumnya):
#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+ (dan mungkin lebih awal):
#pragma warning(push)
/#pragma warning(pop)
Jika memori berfungsi, untuk beberapa versi GCC yang sangat lama (seperti 3.x, IIRC) pragma push / pop harus berada di luar fungsi.
Menyembunyikan detail berdarah
Untuk sebagian besar kompiler dimungkinkan untuk menyembunyikan logika di balik makro yang menggunakan _Pragma
, yang diperkenalkan pada C99. Bahkan dalam mode non-C99, kebanyakan kompiler mendukung _Pragma
; pengecualian besar adalah MSVC, yang memiliki __pragma
kata kunci sendiri dengan sintaks yang berbeda. Standar _Pragma
mengambil string, versi Microsoft tidak:
#if defined(_MSC_VER)
# define PRAGMA_FOO __pragma(foo)
#else
# define PRAGMA_FOO _Pragma("foo")
#endif
PRAGMA_FOO
Secara kasar setara, setelah diproses, untuk
#pragma foo
Ini memungkinkan kami membuat makro sehingga kami dapat menulis kode seperti
MY_DIAGNOSTIC_PUSH
MY_DIAGNOSTIC_DISABLE_DEPRECATED
call_deprecated_function();
MY_DIAGNOSTIC_POP
Dan sembunyikan semua pemeriksaan versi jelek dalam definisi makro.
Cara mudah: Hedley
Sekarang setelah Anda memahami mekanisme cara melakukan hal-hal seperti ini dengan mudah sambil menjaga kode Anda tetap bersih, Anda memahami apa salah satu proyek saya, Hedley . Alih-alih menggali melalui banyak dokumentasi dan / atau menginstal versi sebanyak mungkin kompiler untuk mengujinya, Anda bisa memasukkan Hedley (ini adalah header domain C / C ++ publik tunggal) dan selesai melakukannya. Sebagai contoh:
#include "hedley.h"
HEDLEY_DIAGNOSTIC_PUSH
HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
call_deprecated();
HEDLEY_DIAGNOSTIC_POP
Akan menonaktifkan peringatan tentang memanggil fungsi yang sudah tidak digunakan lagi di GCC, dentang, ICC, PGI, MSVC, TI, IAR, ODS, Pelles, dan mungkin yang lain (saya mungkin tidak akan repot memperbarui jawaban ini ketika saya memperbarui Hedley). Dan, pada kompiler yang tidak dikenal berfungsi, makro tidak akan diproses apa-apa, jadi kode Anda akan terus bekerja dengan kompiler apa pun. Tentu saja HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
bukan satu-satunya peringatan yang diketahui Hedley, juga tidak menonaktifkan peringatan yang bisa dilakukan Hedley, tapi mudah-mudahan Anda mendapatkan idenya.