Tắt một lỗi cảnh báo


114

Có cách nào để tắt chỉ một dòng cảnh báo trong tệp cpp với visual studio không?

Ví dụ: nếu tôi bắt một ngoại lệ và không xử lý nó, tôi sẽ gặp lỗi 4101 (biến cục bộ không được tham chiếu). Có cách nào để bỏ qua điều này chỉ trong hàm đó, nhưng nếu không thì báo cáo nó trong đơn vị biên dịch? Hiện tại, tôi đã đặt #pragma warning (disable : 4101)ở đầu tệp, nhưng điều đó rõ ràng là chỉ tắt nó cho toàn bộ đơn vị.


19
nếu bạn chỉ đề cập đến loại và không đặt tên ngoại lệ, sẽ không có cảnh báo. Vd catch (const std::exception& /* unnamed */) {.... }. Nó không trả lời câu hỏi của bạn, nhưng có thể giải quyết vấn đề của bạn.
Sjoerd

Câu trả lời:


181
#pragma warning( push )
#pragma warning( disable : 4101)
// Your function
#pragma warning( pop ) 

1
@Cookie: vâng, nó hoạt động với bất kỳ đoạn mã nào đi qua trình biên dịch.
Matteo Italia

Để có câu trả lời ngắn gọn, gần đây hơn, hãy xem câu trả lời của Daniel Seither bên dưới.
Dan Nissenbaum

4
clangdường như không hỗ trợ pragma này, nhưng bạn có thể đạt được hiệu quả tương tự với #pragma clang diagnostic push, #pragma clang diagnostic ignored "-Wunused-variable", và #pragma clang diagnostic pop. Xem "Kiểm soát chẩn đoán thông qua Pragmas" trong Hướng dẫn sử dụng Clang
raaries

Vì tôi không thường xuyên sử dụng tính năng này nên khi làm như vậy, tôi thường truy cập trang này để nhắc nhở bản thân về cú pháp. Tôi chỉ đặt nó xung quanh một cuộc gọi đến một hàm không dùng nữa có thể không bao giờ được cập nhật, để cảnh báo không làm phiền tôi trong danh sách trình biên dịch mà tôi quét một cách tôn giáo.
David A. Gray

Đối với Visual Studio, đối số dòng lệnh là /wd4101. Lưu ý rằng không có sự bình thường :giữa cờ và số, và bạn không thể tạo danh sách các số được phân tách bằng dấu phẩy. Đối với các trình biên dịch khác, nó có thể được /nowarn:4101thay thế.
Jesse Chisholm

89

Nếu bạn chỉ muốn loại bỏ cảnh báo trong một dòng mã, bạn có thể sử dụng công suppress cụ chỉ định cảnh báo :

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

Đối với một dòng mã, điều này hoạt động giống như viết như sau:

#pragma warning(push)
#pragma warning(disable: 4101)
// here goes your code where the warning occurs
#pragma warning(pop)

8
Rất hữu ích! Thật không may, nó không hoạt động đối với một dòng bao gồm tiêu đề tạo ra cảnh báo.
Marko Popovic

2
@MarkoPopovic: Công suppresscụ chỉ định hoạt động trên một dòng mã duy nhất, được xử lý trước . Nếu dòng sau #pragma warning(suppress: ...)là một #includechỉ thị (mở rộng tệp được tham chiếu bởi tham số của nó thành đơn vị biên dịch hiện tại), hiệu ứng chỉ áp dụng cho dòng đầu tiên của tệp đó. Điều này là hiển nhiên, vì các cảnh báo được tạo bởi trình biên dịch. Trình biên dịch hoạt động trên mã được xử lý trước.
IInspectable

@IInspectable Trong trường hợp đó, tôi gọi nó là dòng mã được xử lý sau . được xử lý trước nghĩa là nó chưa được dịch bởi bộ xử lý trước.
void.pointer 17/09/19

2
@voi: Phần cuối "-ed" biểu thị quá khứ phân từ . Nó được sử dụng để bày tỏ rằng một cái gì đó đã kết thúc trong quá khứ. Dòng "được xử lý trước" là dòng đã được xử lý hoàn toàn.
IInspectable

29

#pragma push / pop thường là một giải pháp cho loại vấn đề này, nhưng trong trường hợp này, tại sao bạn không loại bỏ biến không được tham chiếu?

try
{
    // ...
}
catch(const your_exception_type &) // type specified but no variable declared
{
    // ...
}

6
Đây không phải là một câu trả lời cho câu hỏi. Được cho là, điều này có thể giải quyết vấn đề của OP, nhưng sẽ không giúp người đọc trong tương lai với một câu hỏi mô phỏng: "làm cách nào để tắt cảnh báo cụ thể cho một phần cụ thể trong mã của tôi?"
Sjoerd

1
@Sjoerd: ba người đã trả lời "câu hỏi chính thức" mà người khác có thể tìm kiếm, vì vậy thay vào đó tôi đã cố gắng đọc giữa các dòng và giải quyết vấn đề thực sự của anh ấy (đến một phút sau nhận xét của bạn :P).
Matteo Italia

11
@Sjoerd với tư cách là một độc giả tương lai, tôi chứng thực rằng câu trả lời này trên thực tế đã giúp ích cho tôi.
Mołot

2
@ Mołot: với tư cách là một nhà văn trước đây, tôi rất vui vì điều đó đã giúp ích. =)
Matteo Italia,

9

Sử dụng #pragma warning ( push ), sau đó #pragma warning ( disable ), sau đó đặt mã của bạn, sau đó sử dụng #pragma warning ( pop )như được mô tả ở đây :

#pragma warning( push )
#pragma warning( disable : WarningCode)
// code with warning
#pragma warning( pop ) 

8

Thí dụ:

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

Pragma này hợp lệ cho C ++ bắt đầu với Visual Studio 2005.
https://msdn.microsoft.com/en-us/library/2c8f766e(v=vs.80).aspx

Pragma KHÔNG hợp lệ cho C # thông qua Visual Studio 2005 thông qua Visual Studio 2015.
Lỗi: "Dự kiến ​​vô hiệu hóa hoặc khôi phục".
(Tôi đoán họ chưa bao giờ triển khai suppress...)
https://msdn.microsoft.com/en-us/library/441722ys(v=vs.140).aspx

C # cần một định dạng khác. Nó sẽ giống như thế này (nhưng không hoạt động):

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

Thay vì suppress, bạn phải disableenable:

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

Điều đó thật là xấu, tôi nghĩ sẽ thông minh hơn nếu chỉ tạo kiểu lại cho nó:

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

5

Thay vì đặt nó trên đầu trang của tập tin (hoặc thậm chí là một tập tin tiêu đề), chỉ cần quấn mã trong câu hỏi với #pragma warning (push), #pragma warning (disable)và phù hợp #pragma warning (pop), như thể hiện ở đây .

Mặc dù có một số tùy chọn khác, bao gồm #pramga warning (once).


5

Một cũng có thể sử dụng UNREFERENCED_PARAMETERđược định nghĩa trong WinNT.H. Định nghĩa chỉ là:

#define UNREFERENCED_PARAMETER(P)          (P)

Và sử dụng nó như:

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

Tại sao bạn lại sử dụng nó, bạn có thể tranh luận rằng bạn có thể bỏ qua chính tên biến. Vâng, có những trường hợp (cấu hình dự án khác nhau, bản dựng Gỡ lỗi / Phát hành) trong đó biến có thể thực sự được sử dụng. Trong một cấu hình khác, biến đó không được sử dụng (và do đó là cảnh báo).

Một số phân tích mã tĩnh có thể vẫn đưa ra cảnh báo cho câu lệnh không vô nghĩa này ( wParam;). Trong trường hợp đó, bạn DBG_UNREFERENCED_PARAMETERcó thể sử dụng tương tự như UNREFERENCED_PARAMETERtrong bản dựng gỡ lỗi và làm P=Ptrong bản dựng phát hành.

#define DBG_UNREFERENCED_PARAMETER(P)      (P) = (P)

1
lưu ý rằng kể từ C ++ 11, chúng tôi có [[maybe_unused]]thuộc tính
metablaster 10/10 '19

2

Nếu bạn muốn tắt unreferenced local variableghi trong một số tiêu đề

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

Và sử dụng

catch(const Except & excpt) {
    ignore(excpt); // No warning
    // ...  
} 

2
Một cuộc gọi chức năng, chỉ để ngăn chặn cảnh báo? Tại sao bạn không làm điều này thay vì (void)unusedVar;:?
Nawaz

@Nawaz: Tôi nghĩ (void)unusedVar;?không phải là C ++ tuân thủ Tiêu chuẩn.
Alexey Malistov

2
Nó là một biểu thức mà giá trị của nó là không có gì. Trong C ++, bạn thậm chí có thể làm được static_cast<void>(unusedVar).
Nawaz


2
§5.2.9 / 4 cho biết, Any expression can be explicitly converted to type “cv void.” The expression value is discardedtheo đó bạn có thể viết static_cast<void>(unusedVar)static_cast<const void>(unusedVar)static_cast<volatile void>(unusedVar). Tất cả các hình thức đều hợp lệ. Tôi hy vọng nó làm sáng tỏ nghi ngờ của bạn.
Nawaz

2

Trong một số trường hợp, bạn phải có một tham số được đặt tên nhưng bạn không sử dụng nó trực tiếp.
Ví dụ: tôi gặp phải nó trên VS2010, khi 'e' chỉ được sử dụng bên trong một decltypecâu lệnh, trình biên dịch sẽ phàn nàn nhưng bạn phải có biến thể được đặt tên e.

Tất cả các #pragmađề xuất không phải đề xuất ở trên đều tổng hợp lại để chỉ thêm một câu lệnh duy nhất:

bool f(int e)
{ 
   // code not using e
   return true;
   e; // use without doing anything
}

1
bây giờ (trong trình biên dịch MS VS2015) điều này gây ra C4702 đang unreachable
Cee McSharpface

2

như @raosystem đã đề cập, nếu bạn đang sử dụng clang gcc, các cảnh báo sẽ theo tên chứ không phải số và bạn sẽ cần thực hiện:

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

thông tin này đến từ đây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.