29

This answer and the comments added to it show a way to disable several compiler warnings using #pragma directives.

Why would one want to do that? Usually the warnings are there for a reason, and I've always felt that they're good reasons. Is there any "valid case" where warnings should be disabled? Right now I can't think of any, but maybe that's just me.

ideasman42
  • 873
  • 6
  • 18
takrl
  • 439
  • 1
  • 8
  • 19
  • 7
    The warning messages are there for a reason, yes, but there's also a reason why they aren't _error_ messages. – Solomon Slow Jun 23 '16 at 13:35
  • 2
    @jameslarge Your comment sums up the situation nicely. A warning is the compiler telling you that a situation is *plausibly wrong*, which implies *possibly right*. If it was *definitely wrong* then it would be an error. Since some warnings may be false positives, there should always be a way to write code such that it eliminates the warning. Unfortunately, sometimes the most pragmatic way to do so is via a pragma; hence the name. – Eric Lippert Jun 23 '16 at 16:38
  • It's not disabling, it's hiding. THe problem will still be there just that you will not see it as is – Sisir Sep 24 '19 at 08:48
  • 1
    You may want to disable a specific compiler warning at a specific place in the code to indicate that it _has been considered_ and the code is intentional (for any reason). By removing the warning you lessen the amount of noise given by the compilation process down to a degree where _new_ warnings do not drown but can be given attention up front. – Thorbjørn Ravn Andersen Nov 09 '20 at 16:49
  • Some compilers (i.e., their compiler writers) warn on situations which are, IMO, sometimes - many times! - acceptable. You don't want to see them. Yet since many of the warnings are _proper_ warnings _always_ you want to run with warnings=errors to get those problems out of your codebase. Thus you disable the warnings you think are frequently too pedantic, too ... fussy. E.g., my pet peeve: A warning that an _argument_ is not used. It's _rarely_ useful. In fact: Never, actually. (You can eliminate the argument _name_ from the signature but you might have good reasons for not doing that.) – davidbak Feb 24 '21 at 18:08
  • My most hated one: if (x >= 0 && x < 100) when x is unsigned. On the other hand: for (x == n-1; x >= 0; —x) is absolutely fatal if x is unsigned. – gnasher729 Mar 07 '21 at 08:05

9 Answers9

14

I've only ever had one situation where I disabled a warning. I consider warnings errors so I wouldn't normally release with warnings. However, while developing an API at a customers I faced the issue that a method that was needed in a migration phase by one application and that no other should ever use had to be included in the library.

The best way I could find to tell all users of the API that they shouldn't call this method was to mark it obsolete. That, however, meant that the one valid use case was marked as a compile warning.

Eric Lippert has written a few posts about warnings where you'll find information about how the compiler team thinks about warnings.

Internal fields of Internal types

Unused using directives are not marked with warnings

Peter Duniho
  • 103
  • 4
Rune FS
  • 314
  • 2
  • 9
11

Here are a few warnings where the documentation gives reasons why you might want to disable them:

Other examples include warnings about using depreciated methods if you know you still want to use the old method or having private members that are never read locally, but with reflection instead.

In my experience C# has less need for disabling warnings than other languages such as C++. This is largely because, as Eric Lippert says in his blog, they "try to reserve warnings for only those situations where we can say with almost certainty that the code is broken, misleading or useless."

Glorfindel
  • 3,137
  • 6
  • 25
  • 33
ICR
  • 481
  • 3
  • 9
  • 3
    Nice. I think the first one is clearest, because it provides a very specific case *and* a justificaiton (the third, for example, shows a peice of code that would never pass review on my team). [This question](http://stackoverflow.com/questions/968293/c-selectively-suppress-custom-obsolete-warnings) talks about obsolete/depricated warnings. Basically, they are still needed in legacy code, but you want to discourage any new code from using them. The legacy code should have the warnings suppressed. – Greg Jackson Jun 24 '11 at 07:23
  • I've done a lot of macro programming in excel and I had to disable warnings for various reasons such as auto save, auto exit, notifications, etc. Of course you may not be on about these warnings... – Dave Mess Jun 24 '11 at 15:10
  • @ICR I don't remember disabling compiler warnings in Java at all. All I do is avoid using deprecated methods. – Mahmoud Hossam Jun 26 '11 at 09:55
  • @Mahmoud I very often find myself having to surpress "unchecked" warnings when doing anything even remotely complex with generics. But it's probably unfair to lump Java in with C++ on the ridiculous warnings front - edited my answer. – ICR Jun 26 '11 at 16:54
  • @ICR Java enforces the use of generics to provide type safety in collections, while some view this as a constraint, I think of it as a feature, it makes writing code a bit painful, but it saves lives, and yeah, C++ compiler output is somewhat scary when it comes to STL or anything with templates. – Mahmoud Hossam Jun 26 '11 at 17:01
  • @Mahmoud oh, I love generics, but type erasure means it can't verify as much as, say C#. Which means when I try and do some of the things I'm used to, I end up having to ignore warnings about unchecked code. – ICR Jun 26 '11 at 17:05
  • @ICR well, they had to make a choice between breaking everybody's code, or using type erasure, and I'm sure that if they did break legacy code, things would've been very bad for Java on the long run. – Mahmoud Hossam Jun 26 '11 at 18:03
  • The first 3 links appear to be broken. – Doc Brown Mar 13 '18 at 07:34
  • Yeah, in my experience, C++ compiler writers are exceptionally anal retentive about warnings. My typical project has a warnings.h I reuse everywhere that has about 10 #pragma warning(disable,) for the ones I particularly find useless and annoying. Because you _want_ to run with warnings=>errors since 98% of the warnings point out an _actual_ potential problem that should be fixed (and is _easily_ fixed). – davidbak Feb 24 '21 at 18:12
10

An example in C that I encounter variants of regularly:

int doSomething(int argument1)
{
#ifdef HARDWARE_TYPE_A
    performAction(argument1);
#else
    displayNotSupportedMessage();
#endif
}

The argument is only relevant on some platforms, but on the ones where it's not relevant my compiler will complain, and since I have warnings converted to errors it will prevent it building.

Converting warnings to errors pretty much requires an escape hatch for "not this one, I know better than the compiler in this case".

pjc50
  • 10,595
  • 1
  • 26
  • 29
  • ... and the standard response is simply casting to `void`. Add `(void)argument1;` to the else-branch. – Deduplicator Nov 09 '20 at 09:54
  • My pet peeve! And I do _not_ like @Deduplicator's remark: Why add additional lines of cruft everywhere to cut out this warning instead of disabling it everywhere with a pragma warning(disable,...)? This warning is _never_ useful. And I have argued this with people before ("never", they say, is too strong) but I have yet to hear a convincing argument where it will, ever, warn you of something you're doing wrong. – davidbak Feb 24 '21 at 18:15
  • @davidbak Most of the time, you can disable (or not enable) any specific warning you think useless or counter-productive. In this case, a slight code-change would remove the warning anyway. – Deduplicator Feb 24 '21 at 19:18
8

Many indispensible Java libraries have never been updated to eliminate the need for unsafe typecasts. Suppressing those warnings is necessary so that other more important warnings will be noticed and corrected.

kevin cline
  • 33,608
  • 3
  • 71
  • 142
5

I do embedded work and I seem to remember a time or two when I've disabled warnings because I was doing something that looked useless to the compiler, but which actually had real-world effects in the hardware.

The only other time is when I'm working on codebases with disparate ideas of some data structure (like how to represent arrays of bytes - char or unsigned char?). In these cases I might disable the warnings because the alternative is to spend days going through the code and either modifying one portion, or putting in hundreds of casts.

Michael Kohne
  • 10,038
  • 1
  • 36
  • 45
3

There are quite a few reasons to selectively disable compiler warnings, even for projects which strive for best practices.

  • Different Compilers (or different versions of the same compilers):
    Compilers handle warnings in subtlety different ways. Giving false-positive warnings that don't impact other compilers. In this case it might make sense to disable the warning for those compilers, instead of editing valid code to quiet a false-positive warning that only impacts certain compilers, especially for older compilers which will eventually become unsupported anyway.
  • With generated code:
    Some warnings related to code hygiene (dead code, duplicate body of conditional statements, comparisons that exceed type limits) can be safely ignored since they are harmless and the compiler will optimize them out.
    Generating code that doesn't raise these harmless warnings is of course an option too, but may be more trouble then its worth.
  • Warnings for external code:
    Perhaps you use a well known qsort or md5 checksum implementation which is included in your project. The code is used by many projects and known to work well, yet there may be some picky warnings which your normally correct for your own code.
    For external code however, it may be less hassle to just disable the warning (assuming its definitely is harmless).
  • Warnings caused by system headers:
    Even though GCC/Clang for example support -isystem, there are cases when differences in system headers cause warnings that can be ignored (perhaps a function has a signed return value on one system but not another), triggering -Wsign-compare warnings.
    Another case may be macros defined in system headers, you could copy-paste the macros into your own code to modify them, but all things considered its better not to have to worry about maintaining macros from 3rd party libraries... so its better just to quiet the warning (perhaps the macro misses a cast causing -Wsign-conversion eg).
  • Unused warnings in stub code:
    You may warn of unused parameters, however when stubbing out an entire library in a single file that only contains stub functions - its not helpful to force (void)arg1; (void)arg2; (void)arg3; ... in the body of every stub function.
    Better just suppress -Wunused-parameter in this case.

Note that in all these examples, its assumed disabling the warnings is not going to hide real bugs, eg: -Wredundant-decls, -Wunused-parameter, -Wdouble-promotion, perhaps -Wpedantic... and that you know what you're doing!

ideasman42
  • 873
  • 6
  • 18
2

Valid or not, it is sometimes done to bypass the "treat warnings as errors" directive on the build server.

Other than that I can't think of any either. Disabled warnings are usually a sign of an "ugly hax"...

2

Last time we disabled certain warnings, it was because an intern had left us with bad code. I've got it working a lot better, with clear conversion boundaries replacing the haphazard data representation.

In the meantime, we needed to compile it in, and we wanted the "warnings are errors" option on, so we suppressed some of the warnings.

David Thornley
  • 20,238
  • 2
  • 55
  • 82
2

Edit [2020/11/09]: With the advent of noexcept into the language and the deprecation and removal of the Dynamic exception specification that is referenced, this answer is out-of-date; but, it is being kept for historical reasons. Original text follows below the break.


Currently, the only warning I ever ignore is

  warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow)  

Because microsoft does not implement the C++ specification (the documentation even says they don't!) and allow functions to declare specific throws and all functions can only throw either throw() or throw(...), i.e nothing or everything.

From HelpViewer 1.1:

 A function is declared using exception specification, which Visual C++ accepts but does not implement. Code with exception specifications that are ignored during compilation may need to be recompiled and linked to be reused in future versions supporting exception specifications. 
Casey
  • 425
  • 3
  • 13