Nonaktifkan kesalahan peringatan tunggal

115

Apakah ada cara untuk menonaktifkan hanya satu baris peringatan di file cpp dengan visual studio?

Misalnya, jika saya menangkap pengecualian dan tidak menanganinya, saya mendapatkan kesalahan 4101 (variabel lokal tidak direferensikan). Apakah ada cara untuk mengabaikan ini hanya di fungsi itu, tetapi melaporkannya ke unit kompilasi? Saat ini, saya meletakkannya #pragma warning (disable : 4101)di bagian atas file, tetapi itu jelas hanya mematikannya untuk seluruh unit.

Kue kering
sumber
19
jika Anda hanya menyebutkan jenisnya dan tidak menyebutkan pengecualiannya, tidak akan ada peringatan. Mis catch (const std::exception& /* unnamed */) {.... }. Itu tidak menjawab pertanyaan Anda, tetapi mungkin menyelesaikan masalah Anda.
Sjoerd

Jawaban:

182
#pragma warning( push )
#pragma warning( disable : 4101)
// Your function
#pragma warning( pop ) 
Andreas Brinck
sumber
1
@ Cookie: ya, ini berfungsi untuk semua bagian kode yang melalui kompilator.
Matteo Italia
Untuk jawaban yang lebih baru dan ringkas, lihat jawaban Daniel Seither, di bawah.
Dan Nissenbaum
4
clangtampaknya tidak mendukung pragma ini, tetapi Anda dapat mencapai efek yang sama dengan #pragma clang diagnostic push, #pragma clang diagnostic ignored "-Wunused-variable", dan #pragma clang diagnostic pop. Lihat "Mengontrol Diagnositika Melalui Pragmas" di Panduan Pengguna Clang
rampion
Karena saya jarang menggunakan fitur ini, ketika saya melakukannya, saya biasanya membuka halaman ini untuk mengingatkan diri saya tentang sintaks. Saya hanya menaruhnya di sekitar panggilan ke fungsi usang yang mungkin tidak pernah diperbarui, sehingga peringatan itu tidak akan mengganggu saya dalam daftar kompiler, yang saya pindai secara religius.
David A. Gray
Untuk Visual Studio, argumen baris perintah adalah /wd4101. Perhatikan bahwa tidak ada angka normal :antara bendera dan angka, dan Anda tidak dapat membuat daftar angka yang dipisahkan koma. Untuk kompiler lain mungkin menjadi /nowarn:4101gantinya.
Jesse Chisholm
89

Jika Anda hanya ingin menyembunyikan peringatan dalam satu baris kode, Anda dapat menggunakan suppress penentu peringatan :

#pragma warning(suppress: 4101)
// here goes your single line of code where the warning occurs

Untuk satu baris kode, cara kerjanya sama seperti penulisan berikut:

#pragma warning(push)
#pragma warning(disable: 4101)
// here goes your code where the warning occurs
#pragma warning(pop)
Daniel Seither
sumber
8
Sangat berguna! Sayangnya, ini tidak berfungsi untuk satu baris yang menyertakan header yang menghasilkan peringatan.
Marko Popovic
2
@MarkoPopovic: Penentu suppressberoperasi pada satu baris kode yang telah diproses sebelumnya. Jika baris berikut #pragma warning(suppress: ...)adalah #includearahan (yang memperluas file yang direferensikan oleh parameternya ke dalam unit kompilasi saat ini), efeknya berlaku untuk baris pertama file itu saja. Ini harusnya jelas, karena peringatan dibuat oleh kompilator. Kompilator beroperasi pada kode yang telah diproses sebelumnya.
IInspectable
@IInspectable Dalam hal ini saya akan menyebutnya baris kode pasca-diproses . pra-proses berarti belum diterjemahkan oleh preprocessor.
void.pointer
2
@voi: Akhiran "-ed" menandakan past participle . Ini digunakan untuk mengungkapkan, bahwa sesuatu telah berakhir di masa lalu. Garis "pra-proses" adalah garis yang telah diproses sepenuhnya.
IInspectable
29

#pragma push / pop sering menjadi solusi untuk masalah semacam ini, tetapi dalam kasus ini mengapa Anda tidak menghapus variabel yang tidak direferensikan saja?

try
{
    // ...
}
catch(const your_exception_type &) // type specified but no variable declared
{
    // ...
}
Matteo Italia
sumber
6
Ini bukan jawaban atas pertanyaan itu. Memang, ini mungkin menyelesaikan masalah OP, tetapi tidak akan membantu pembaca di masa mendatang dengan pertanyaan yang sama: "bagaimana cara mematikan peringatan khusus untuk bagian tertentu dari kode saya?"
Sjoerd
1
@Sjoerd: tiga orang sudah menjawab "pertanyaan resmi" yang mungkin dicari orang lain, jadi saya mencoba membaca yang tersirat dan menyelesaikan masalah sebenarnya (tiba satu menit setelah komentar Anda :P).
Matteo Italia
11
@Sjoerd sebagai pembaca masa depan, saya membuktikan bahwa jawaban ini sebenarnya membantu saya.
Mołot
2
@ Mołot: sebagai penulis sebelumnya, saya senang ini membantu. =)
Matteo Italia
9

Gunakan #pragma warning ( push ), lalu #pragma warning ( disable ), masukkan kode Anda, lalu gunakan #pragma warning ( pop )seperti yang dijelaskan di sini :

#pragma warning( push )
#pragma warning( disable : WarningCode)
// code with warning
#pragma warning( pop ) 
gigi tajam
sumber
8

Contoh:

#pragma warning(suppress:0000)  // (suppress one error in the next line)

Pragma ini berlaku untuk C ++ yang dimulai dengan Visual Studio 2005.
https://msdn.microsoft.com/en-us/library/2c8f766e(v=vs.80).aspx

Pragma TIDAK valid untuk C # melalui Visual Studio 2005 melalui Visual Studio 2015.
Kesalahan: "Diharapkan menonaktifkan atau memulihkan".
(Saya kira mereka tidak pernah sempat menerapkan suppress...)
https://msdn.microsoft.com/en-us/library/441722ys(v=vs.140).aspx

C # membutuhkan format yang berbeda. Ini akan terlihat seperti ini (tetapi tidak berfungsi):

#pragma warning suppress 0642  // (suppress one error in the next line)

Dari pada suppress , Anda harus disabledan enable:

if (condition)
#pragma warning disable 0642
    ;  // Empty statement HERE provokes Warning: "Possible mistaken empty statement" (CS0642)
#pragma warning restore 0642
else

Itu SANGAT jelek, saya pikir lebih pintar untuk hanya menatanya kembali:

if (condition)
{
    // Do nothing (because blah blah blah).
}
else
A876
sumber
5

Alih-alih meletakkannya di atas file (atau bahkan file header), cukup bungkus kode yang dimaksud dengan #pragma warning (push), #pragma warning (disable)dan pencocokan #pragma warning (pop), seperti yang ditunjukkan di sini .

Meski ada beberapa opsi lain, termasuk #pramga warning (once).

Christian.K
sumber
5

Satu juga dapat menggunakan UNREFERENCED_PARAMETERdidefinisikan dalam WinNT.H. Definisinya hanya:

#define UNREFERENCED_PARAMETER(P)          (P)

Dan gunakan seperti:

void OnMessage(WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(wParam);
    UNREFERENCED_PARAMETER(lParam);
}

Mengapa Anda menggunakannya, Anda mungkin berpendapat bahwa Anda bisa menghilangkan nama variabel itu sendiri. Ada beberapa kasus (konfigurasi project berbeda, build Debug / Rilis) di mana variabel mungkin benar-benar digunakan. Dalam konfigurasi lain variabel itu tidak digunakan (dan karenanya peringatan).

Beberapa analisis kode statis mungkin masih memberikan peringatan untuk pernyataan tidak masuk akal ini ( wParam;). Dalam hal ini, Anda dapat menggunakan DBG_UNREFERENCED_PARAMETERyang sama seperti UNREFERENCED_PARAMETERpada build debug, dan melakukannya P=Pdalam build rilis.

#define DBG_UNREFERENCED_PARAMETER(P)      (P) = (P)
Ajay
sumber
1
perhatikan bahwa karena C ++ 11 kami memiliki [[maybe_unused]]atribut
metablaster
2

Jika Anda ingin menonaktifkan unreferenced local variabletulis di beberapa header

template<class T>
void ignore (const T & ) {}

dan gunakan

catch(const Except & excpt) {
    ignore(excpt); // No warning
    // ...  
} 
Alexey Malistov
sumber
2
Panggilan fungsi, hanya untuk menekan peringatan? Mengapa Anda tidak melakukan ini sebagai gantinya: (void)unusedVar;?
Nawaz
@Nawaz: Saya pikir (void)unusedVar;?bukan C ++ standar konforman.
Alexey Malistov
2
Itu adalah ekspresi yang nilainya tidak ada artinya. Di C ++, Anda bahkan dapat melakukannya static_cast<void>(unusedVar).
Nawaz
2
@Tokopedia Penjelasan Herb Sutter: herbutter.com/2009/10/18/mailbag-shutting-up-compiler-warnings
Alexey Malistov
2
§5.2.9 / 4 mengatakan, yang Any expression can be explicitly converted to type “cv void.” The expression value is discardedmenurutnya Anda dapat menulis static_cast<void>(unusedVar)dan static_cast<const void>(unusedVar)dan static_cast<volatile void>(unusedVar). Semua formulir valid. Saya harap ini menjelaskan keraguan Anda.
Nawaz
2

Dalam situasi tertentu Anda harus memiliki parameter bernama tetapi Anda tidak menggunakannya secara langsung.
Sebagai contoh, saya menemukannya di VS2010, ketika 'e' hanya digunakan di dalam sebuah decltypepernyataan, kompilator mengeluh tetapi Anda harus memiliki variabel bernama e.

Semua non- #pragmasaran di atas semuanya diringkas menjadi hanya menambahkan satu pernyataan:

bool f(int e)
{ 
   // code not using e
   return true;
   e; // use without doing anything
}
Adi Shavit
sumber
1
sekarang (dalam kompiler MS VS2015) ini menyebabkan kode C4702 tidak dapat dijangkau
Cee McSharpface
2

seperti yang disebutkan @rampion, jika Anda berada di clang gcc, peringatannya adalah berdasarkan nama, bukan angka, dan Anda harus melakukan:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-variable"
// ..your code..
#pragma clang diagnostic pop

info ini berasal dari sini

orion elenzil
sumber