Is using #pragma warning push/pop the right way to temporarily alter warning level?

C++Visual C++WarningsCompiler WarningsPragma

C++ Problem Overview


Once in a while it's difficult to write C++ code that wouldn't emit warnings at all. Having warnings enabled is however a good idea. So it is often necessary to disable warnings around some specific construct and have them enables in all other pieces of code.

I've seen two ways of doing that so far.

The first one is to use #pragma warning( push ) and #pragma warning( pop ):

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

The second is to use #pragma warning( default ):

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

The problem I see in the second variant is that it discards the original warning level - the warning might have been off before that or its warning level might have been altered. Using default would discard those alterations.

The first approach looks clean. Are there any problems with it? Are there any better ways to achieve the same?

C++ Solutions


Solution 1 - C++

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

Solution 2 - C++

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 )

Solution 3 - C++

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 :)

Solution 4 - C++

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

Solution 5 - C++

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.

Solution 6 - C++

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.

Solution 7 - C++

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 )

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsharptoothView Question on Stackoverflow
Solution 1 - C++user2288008View Answer on Stackoverflow
Solution 2 - C++m3tikn0bView Answer on Stackoverflow
Solution 3 - C++GozView Answer on Stackoverflow
Solution 4 - C++ronagView Answer on Stackoverflow
Solution 5 - C++Steve TownsendView Answer on Stackoverflow
Solution 6 - C++Kirill V. LyadvinskyView Answer on Stackoverflow
Solution 7 - C++CharlieView Answer on Stackoverflow