使用 # 杂注警告推/弹出是临时更改警告级别的正确方法吗?

偶尔很难编写完全不会发出警告的 C + + 代码。然而,启用警告是一个好主意。因此,通常有必要禁用某些特定构造周围的警告,并在所有其他代码段中启用这些警告。

到目前为止,我已经看到了两种方法。

第一种是使用 #pragma warning( push )#pragma warning( pop ):

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

第二种是使用 #pragma warning( default ):

 #pragma warning( disable: ThatWarning )
//code with ThatWarning here
#pragma warning( default: ThatWarning )

我在第二个变体中看到的问题是,它丢弃了原来的警告级别——在此之前警告可能已经关闭,或者警告级别可能已经更改。使用 default将放弃这些更改。

第一种方法看起来很干净。它有什么问题吗? 有没有更好的方法来达到同样的效果?

64777 次浏览

The first method is the best way to do it, IMO. I know of no problems with it.

Simply bear in mind that a #pragma is compiler specific so don't expect it to work on every compiler out there :)

I have no problems with the first variant. May be the better way is to use the following:

 #pragma warning( push )
#pragma warning( once: ThatWarning )
//code with ThatWarning here
#pragma warning( pop )

This will let you know that there're still warnings in the code, but the warning messages will not be so annoying. But that is the matter of taste.

The correct approach (although a bit ugly)

#ifdef _MSC_VER
#pragma warning( push )
#pragma warning( once: ThatWarning )
#endif
//code with ThatWarning here
#ifdef _MSC_VER
#pragma warning( pop )
#endif

You can disable specific warnings in the project or file options and this setting applies as the 'default' per those #pragmas at the relevant scope. Some of the warnings in VS2005 are so useless/annoying that this cleans up the output quite a bit, if using /W4.

This is in Properties under Configuration Properties -> C/C++ -> Advanced.

Too late for sharptooth but for all the googlers out there:

#pragma warning ( suppress: ThatWarning )
// one single line with ThatWarning

is short for (generally since VS 2008, but in VS 2005 for Code Analyzer warnings only):

#pragma warning ( push )
#pragma warning ( disable: ThatWarning )
// one single line with ThatWarning
#pragma warning ( pop )

This will work with multiple compilers (and different versions of compilers).

Header "push"

#if defined(__clang__)
# pragma clang diagnostic push
#endif


#if defined(_MSC_VER)
# pragma warning(push)
#endif


#if defined(YOUR_FAVORITE_COMPILER)
# pragma your compiler push warning
#endif

Header "pop"

#if defined(__clang__)
# pragma clang diagnostic pop
#endif


#if defined(_MSC_VER)
# pragma warning(pop)
#endif

Some warning

#if defined(__clang__)
# pragma clang diagnostic ignored "-Wunused-parameter"
# pragma clang diagnostic ignored "-Wunused-variable"
#  if __has_warning("-Wnew-special-warning")
#   pragma clang diagnostic ignored "-Wnew-special-warning"
#  endif
#endif


#if defined(_MSC_VER)
# pragma warning(disable: 4100) // unreferenced formal parameter
# if _MSC_VER > _MSC_SOME_VERSION
#  pragma warning(disable: xxxx) // disable one more for special version
# endif
#endif

Usage

// This code reports warnings
// ...
#include <ignore_compiler_warning/push>
#include <ignore_compiler_warning/warning_type_1>
#include <ignore_compiler_warning/warning_type_2>
#include <ignore_compiler_warning/warning_type_3>
// This code ignores warnings type_{1,2,3}
// ...
#include <ignore_compiler_warning/pop>
// Back to reporting warnings
// ...

Additionally include guards can check that there is no double push/pop/disable-warning pragmas.

Update

The first approach allows you change the specific warning setting in a local scope. It first stores all the current warning state by push into stack, apply your warning modifications, then restore (pop) to last warning state.

#pragma warning( push ) #pragma warning( once: ThatWarning ) //code with ThatWarning here #pragma warning( pop )