85

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?

Steve Townsend
  • 53,498
  • 9
  • 91
  • 140
sharptooth
  • 167,383
  • 100
  • 513
  • 979
  • Portability, but as this is tagged with visual-c++, that's probably not an issue for you. Sadly, there appears no solution that falls anywhere near "ascetically pleasing". I always go with the push/pop method. – Mark Storer Apr 22 '19 at 13:36

7 Answers7

51

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

48

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 )
m3tikn0b
  • 1,298
  • 8
  • 16
  • Thanks a lot! `suppress` is definitely the right answer here, and much more elegant than `push/disable/pop` or `disable/enable`. – Nicu Stiurca Feb 18 '16 at 22:08
  • was the only working way in vs2012 , push disable etc ..did not work – Michel Sanches Aug 18 '16 at 13:54
  • I suspect this is the method that most coders want. – David A. Gray Aug 02 '18 at 21:21
  • Another word to the wise; lose the C prefix; just use the number. Otherwise, the #pragma directive generates yet more warnings and does nothing. – David A. Gray Aug 02 '18 at 21:55
  • 3
    Although this is the most elegant method (if there can be said to be such a thing) it doesn't always work as intended. As always, the devil is in the detail: `#pragma warning (suppress)` only works on the next **line** of code, not the next **block**. I bring this up since TS stated "code with warning". – marcbf Jul 16 '19 at 06:13
41

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

Goz
  • 61,365
  • 24
  • 124
  • 204
  • 9
    I came up with a possible annoying problem to the first approach. If the `\\code with ThatWarning here` has a (3rd party) header in it, and that header has a `#pragma warning( disable: AnotherWarning)` then the pop turns off the disable. While arguably this is a good thing, the library designer may be doing something in a template that generates a warning, that they have determined is safe. Now any use of that template in your code will generate this warning, but it will be flagged as the library. It is not clear at all what line of your code is triggering a warning in the library. – Downward Facing God Aug 08 '11 at 15:37
  • 3
    @DownwardFacingGod: Late-reply-o-rama .... but ... that same issue would occur with the the other method too ... – Goz Mar 13 '16 at 19:20
  • 1
    As stated here correctly, the first method is the best and there is nothing wrong with that. This point clearly stated in "C++ Coding standards 101 Rules, Guidelines and Best Practices", by Herb Sutter and Andrei Alexandrescu,1st Edition, 2005 (page 19). – amirfg Jul 17 '19 at 11:20
14

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
ronag
  • 49,529
  • 25
  • 126
  • 221
  • 13
    TS wants to temporarily disable a warning for some part of code. #pragma warning(once) won't work, since it still allows the warning to be displayed (just once). I wonder if the upvoters actually tested the solution. (I did, it didn't work). – Alex Che Dec 22 '14 at 16:00
  • 3
    'once' vs 'disable'. I believe our humble readers will figure it out. Stack overflow readers are clearly among the finest humanity has to offer. Or something. – Mark Storer Apr 22 '19 at 13:30
3

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.

Steve Townsend
  • 53,498
  • 9
  • 91
  • 140
2

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.

Kirill V. Lyadvinsky
  • 97,037
  • 24
  • 136
  • 212
  • This warning: http://msdn.microsoft.com/en-us/library/1ywe7hcy(VS.80).aspx is bleeding annoying even if you only see it once ;) – Goz Nov 16 '10 at 11:42
  • 1
    The problem here is that it can be useful to make the compiler "treat warnings as errors". For errors that can't be fixed (i.e. some 3rd party dependency) then you have to disable safely. – Downward Facing God Aug 08 '11 at 15:45
0

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 )

Charlie
  • 33
  • 5