75

I'm starting a new BREW project, and I'd like to compile with Warning Level 4 (/W4) to keep the application code nice and clean. The problem is that the BREW headers themselves don't compile cleanly with /W4.

In gcc you can differentiate between application and system headers by using -I and -isystem, and then by default gcc doesn't report any compilation warnings in system headers. Is there an equivalent mechanism in Visual C++?

Prof. Falken
  • 24,226
  • 19
  • 100
  • 173
Bob Whiteman
  • 2,481
  • 2
  • 23
  • 27
  • vote for https://visualstudio.uservoice.com/forums/121579-visual-studio-ide/suggestions/14717934-add-a-cl-exe-option-for-system-headers-like-gcc-s – Trass3r Jul 20 '17 at 11:41
  • This^ UserVoice instance is no longer available. – Henry Aloni Dec 16 '20 at 12:32
  • @HenryAloni userVoice for visual-studio was migrated to https://developercommunity.visualstudio.com/ however I was not able to find the migrated ticket using the search function there. – Étienne Jan 24 '22 at 15:22
  • See https://devblogs.microsoft.com/cppblog/customized-warning-levels-and-code-analysis-for-external-headers/ – Étienne Jan 24 '22 at 15:25

5 Answers5

116

Use this method around (a) header(s) that you cannot or don't want to change, but which you need to include.

You can selectively, and temporarily disable all warnings like this:

#pragma warning(push, 0)
// Some include(s) with unfixable warnings
#pragma warning(pop)

Instead of 0 you can optionally pass in the warning number to disable, so something like:

#pragma warning(push)
#pragma warning(disable : 4081)
#pragma warning(disable : 4706)
// Some code
#pragma warning(pop)
BullyWiiPlaza
  • 17,329
  • 10
  • 113
  • 185
Brian R. Bondy
  • 339,232
  • 124
  • 596
  • 636
  • 5
    StackOverflow rocks. Thanks for the complete answer. This solution is relatively annoying because it has to be done correctly in every source file, whereas in gcc you just configure your makefile correctly once. – Bob Whiteman Mar 30 '10 at 01:02
  • 2
    @Bob: No prob, glad to help. You could try putting those includes inside a different file and putting your include warning disables around just that one file. – Brian R. Bondy Mar 30 '10 at 01:03
  • That's not particularly practical for BREW either, because there isn't one single base header file (or small group of header files) to wrap with an intermediate header. A typical project will have many source and header files, each of which includes a different subset of the BREW headers. I could potentially make one super-header that includes ALL BREW headers, and then pre-compile it to keep builds efficient. This technique would only work for Visual C++, and BREW projects need to build with at least two compilers (Visual C++ for simulator builds, and gcc or ARM for handsets). – Bob Whiteman Mar 30 '10 at 18:10
  • 6
    As an additional note, it is possible to disable multiple warnings in a single line like this: `#pragma warning( disable : 4081 4706 )` – GOTO 0 Dec 31 '12 at 14:46
  • 12
    `warning(push, 0)` doesn't seem to work from inside a cpp, only from inside a header. – Yakov Galka Nov 05 '15 at 16:31
  • @ybungalobill: Probably you instantiate template defined in a header. In this case I believe that warning will be produced at instantiation place (in .cpp file body), so your pragma directive doesn't cover it. But I may be wrong. – magras Jan 20 '16 at 17:58
  • 2
    If you want to use #pragma inside #define you can do: `#define DISABLE_BAD_WARN __pragma(warning( disable : 4244 4626 5027 5031 4514))` – Shital Shah Dec 22 '16 at 05:55
  • I did this around external headers, like opencv2, but I'm still getting all warnings from it. – Pedro77 Apr 14 '22 at 13:36
  • This doesn't work if the warnings are from usage of the header inside your code. For example when you use a template from the header, it make the compiler read through the headers again and warn about stuff. – Yomi1984 Jun 26 '22 at 07:59
23

Visual C++ team has just added support for warning levels in external headers. You can find the details in their blog post: Broken Warnings Theory.

In essence it does automatically what the suggestions here were recommending to do manually: pushes new warning level right before #include directive and pops it up right after. There are additional flags to specify locations of external headers, flag to treat all <> includes as external, #pragma system_header and a feature not available in Clang or GCC (as of this writing) to see warnings in external headers across template instantiation stack when the template was instantiated in the user code.

Besides the comments under that post, you can also find some useful discussion in a reddit announcement for that post.

Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
solodon
  • 516
  • 5
  • 7
  • 3
    Checking in: As of October 2019, this option is still flawed, but pretty useful nonetheless. It's a good basis, but still not nearly up to the level of `-isystem` or similar; at the moment, wrapping includes in warning-disable pragmas still handles certain things noticeably better. – Justin Time - Reinstate Monica Oct 03 '19 at 18:26
  • 1
    @JustinTime2ReinstateMonica can you elaborate what exactly doesn't work? – Alexey Andronov Dec 06 '19 at 17:29
  • Unfortunately, @AlexeyAndronov, I can't remember what it was that didn't seem to work a few months ago; if I remember, and it still hasn't been fixed, I'll make a note of it here. – Justin Time - Reinstate Monica Jan 12 '20 at 20:56
  • 2
    It seems that flag /external mentioned in the article was in a Preview version. I can't find any mention of it in the VS2019 compiler flags documentation... Does anyone know what happened to this flag? – dats Oct 30 '20 at 10:30
  • @AlexeyAndronov /external:anglebrackets doesn't work with /analyze, infact none of the default include or excludepath libraries get excluded. It is just BAD! – fedvasu Feb 26 '21 at 13:14
  • @fedvasu `/analyze:external-` – ixSci Jan 19 '22 at 10:40
6

I don't believe Visual C++ lets you differentiate. You can fake it by using #pragma warning around the include:

#pragma warning(push, 0)
#include "mywarningheader.h"
#pragma warning(pop)
Dan Story
  • 9,985
  • 1
  • 23
  • 27
  • 2
    @einpoklum Differentiate between your application-specific headers and other (third-party, system, etc.) headers which you cannot change. – Torben L. May 13 '14 at 15:51
  • I did this around external headers, still getting all warnings, from mat.hpp, etc. – Pedro77 Apr 14 '22 at 13:35
5

The /external:anglebrackets /external:W0 compiler flags disable warnings on the headers imported with #include <...>.

You can change the W0 to W1, W2, W3, or W4, to set a different warning level for those.

  • 1
    closest to the best up-to-date answer!! I think, that's the best you can do nowadays in lieu of -isystem – IceFire Feb 13 '23 at 11:08
3

It seems like there is an answer to this.

this post talks about /external:I that can be used to include headers with a special set of warnings.

I have not tested it myself, but the blog post is from 2017.

Lasersköld
  • 2,028
  • 14
  • 20