I'm running Visual Studio 2017. I'm trying to add a Scripting Language called ChaiScript to my project, but it generates A LOT of warnings when I have /Wall on, and I also have treat warnings as errors on (I prefer this to stay like this).
So I figured I would try to temporarily disable all the warnings when including the ChaiScript header file (only need to include 1 file). At first I did this...
#pragma warning( disable : 4061 )
#pragma warning( disable : 4068 )
#pragma warning( disable : 4191 )
#pragma warning( disable : 4355 )
#pragma warning( disable : 4365 )
#pragma warning( disable : 4371 )
#pragma warning( disable : 4464 )
#pragma warning( disable : 4514 )
#pragma warning( disable : 4571 )
#pragma warning( disable : 4623 )
#pragma warning( disable : 4625 )
#pragma warning( disable : 4626 )
#pragma warning( disable : 4668 )
#pragma warning( disable : 4710 )
#pragma warning( disable : 4774 )
#pragma warning( disable : 4820 )
#pragma warning( disable : 5026 )
#pragma warning( disable : 5027 )
#include <chaiscript\chaiscript.hpp>
This works, I can compile... However, I then wanted to have these warnings re-enabled for the rest of the compile process.... So I turned it into this...
#pragma warning( push )
#pragma warning( disable : 4061 )
#pragma warning( disable : 4068 )
#pragma warning( disable : 4191 )
#pragma warning( disable : 4355 )
#pragma warning( disable : 4365 )
#pragma warning( disable : 4371 )
#pragma warning( disable : 4464 )
#pragma warning( disable : 4514 )
#pragma warning( disable : 4571 )
#pragma warning( disable : 4623 )
#pragma warning( disable : 4625 )
#pragma warning( disable : 4626 )
#pragma warning( disable : 4668 )
#pragma warning( disable : 4710 )
#pragma warning( disable : 4774 )
#pragma warning( disable : 4820 )
#pragma warning( disable : 5026 )
#pragma warning( disable : 5027 )
#include <chaiscript\chaiscript.hpp>
#pragma warning( pop )
Now I thought this would make it so it would compile the header without the warnings, then go back to checking for those warnings.... but it seems that after I do this... I still get 4 C4710 warnings... Am I doing something wrong?
Add a #pragma warning(push, 3) before all the disables and a #pragma warning(pop) after the include.
In this particular case, the problem is likely that, although the warning was disabled when compiling the function definition, it was re-enabled where the compiler had the option of inlining it. There doesn't seem to be a practical solution to that.
Microsoft lists the warnings that are off-by-default. The difference between /W4 and /Wall is that /Wall enables the off-by-default warnings. The off-by-default warnings are off-by-default because they are either low value and/or because you'd likely get many false positives. It might be instructive to occasionally check your project with /Wall to see if there's any useful information in there, but it doesn't seem practical to have them enabled all the time.
I'm a huge fan of pushing the warning level as high as is practical, but /Wall is a step too far for me. I recommend /W4 with /WX everywhere. If necessary for third-party code, drop down to /W3 using #pragma warning(push/pop) as you've shown. In my experience, all the Microsoft headers compile cleanly at /W4.
Related
I am beginning to learn C++ and read that increasing the warning level is a good idea to be more careful in writing your code. I am using Visual Studio 2015 (community version)
However, after doing so, I receive hundreds of errors (edit: WARNINGS treated as errors, sorry) even in basic programs. These are all coming from the math header, and they say that "unreferenced inline function has been removed". Seems like every method I don't use is causing a warning.
Why is this happening, and how can I fix it?
With Visual C++ you should use /W4, not /Wall which is impractical. If warning level 4 still produces sillywarnings, e.g. from standard headers, then consider using my old MSVC "no sillywarnings" header, or a suitable extension of it. Preferably then via a forced include compiler option.
For working with Visual C++ in the command line I generally use the following environment variable:
CL=/nologo /EHsc /GR /W4 /FI "iso646.h"
Apparently there is now automatic suppression of warnings from system headers, so it's not a problem.
Please note that while the holy C++ standard does not differentiate between different kinds of diagnostics, as a de facto standard C++ compilers and linkers differentiate between
Errors:
An error diagnostic means that no executable (or object file) is produced.
Warnings:
A warning diagnostic means that something was likely to be wrong, or at least was somewhat questionable, but the compiler or linker or other tool carried on assuming you knew what you were doing.
Relevant MSVC-specific headers you can force-include (option /FI), including a more up to date version of the no sillywarnings header:
msvc_less_errors_as_warnings_please.hpp
#pragma once
// p/cppx/core_language_support/compiler_specific/msvc_less_errors_as_warnings_please.hpp
// Copyright © Alf P. Steinbach 2015. Boost Software License 1.0.
#ifndef _MSC_VER
# error This file is specific to the MSVC (Microsoft Visual C++) compiler.
#endif
#pragma warning( error: 4566 ) // Character ... cannot be represented -- is error.
#pragma warning( error: 4627 ) // Source code has been ignored – is error.
msvc_more_warnings_please.hpp
#pragma once
// p/cppx/core_language_support/compiler_specific/msvc_more_warnings_please.hpp
// Copyright © Alf P. Steinbach 2015. Boost Software License 1.0.
#ifndef _MSC_VER
# error This file is specific to the MSVC (Microsoft Visual C++) compiler.
#endif
#pragma warning( push, 4 ) // Warning level 4 (max). MSVC /Wall is impractical.
msvc_no_sillywarnings_please.hpp
#pragma once
// p/cppx/core_language_support/compiler_specific/msvc_no_sillywarnings_please.hpp
// Copyright © Alf P. Steinbach 2010 – 2015. Boost Software License 1.0.
#ifndef _MSC_VER
# error This file is specific to the MSVC (Microsoft Visual C++) compiler.
#endif
#ifndef CPPX_ALLOW_WP64
# // The /Wp64 option generates spurious warnings when a __w64 type argument selects
# // a correct overload with non-__w64 formal argument type, i.e. for <<. In newer
# // versions of MSVC this option is deprecated. It Really Annoyed a lot of people!
# ifdef _Wp64
# error Do not use the /Wp64 option: use a 64-bit compiler to detect 64-bit portability issues.
# endif
#endif
// The following are real warnings but are generated by almost all MS headers, including
// standard library headers, so it's impractical to leave them on.
#pragma warning( disable: 4619 ) // there is no warning number 'XXXX'
#pragma warning( disable: 4668 ) // XXX is not defined as a preprocessor macro
// The following are pure sillywarnings:
#pragma warning( disable: 4061 ) // enum value is not *explicitly* handled in switch
#pragma warning( disable: 4063 ) // case 'nn' is not a valid value for switch of enum 'Name'
#pragma warning( disable: 4099 ) // first seen using 'struct' now seen using 'class'
#pragma warning( disable: 4127 ) // conditional expression is constant
#pragma warning( disable: 4180 ) // qualifier applied to function type has no meaning
#pragma warning( disable: 4217 ) // member template isn't copy constructor
#pragma warning( disable: 4250 ) // inherits (implements) some member via dominance
#pragma warning( disable: 4251 ) // needs to have dll-interface to be used by clients
#pragma warning( disable: 4275 ) // exported class derived from non-exported class
#pragma warning( disable: 4347 ) // "behavior change", function called instead of template
#pragma warning( disable: 4355 ) // "'this': used in member initializer list
#pragma warning( disable: 4373 ) // override when arg types differ by const/volatile qualifiers
#pragma warning( disable: 4428 ) // MSVC 9: universal-character-name encountered in source
#pragma warning( disable: 4459 ) // local declaration hides global declaration
#pragma warning( disable: 4505 ) // unreferenced function has been removed
#pragma warning( disable: 4510 ) // default constructor could not be generated
#pragma warning( disable: 4511 ) // copy constructor could not be generated
#pragma warning( disable: 4512 ) // assignment operator could not be generated
#pragma warning( disable: 4513 ) // destructor could not be generated
#pragma warning( disable: 4610 ) // can never be instantiated user defined constructor required
#pragma warning( disable: 4623 ) // default constructor could not be generated
#pragma warning( disable: 4624 ) // destructor could not be generated
#pragma warning( disable: 4625 ) // copy constructor could not be generated
#pragma warning( disable: 4626 ) // assignment operator could not be generated
#pragma warning( disable: 4640 ) // a local static object is not thread-safe
#pragma warning( disable: 4646 ) // noreturn function should have a void return type
#pragma warning( disable: 4661 ) // a member of the template class is not defined.
#pragma warning( disable: 4670 ) // a base class of an exception class is inaccessible for catch
#pragma warning( disable: 4672 ) // a base class of an exception class is ambiguous for catch
#pragma warning( disable: 4673 ) // a base class of an exception class is inaccessible for catch
#pragma warning( disable: 4675 ) // resolved overload was found by argument-dependent lookup
#pragma warning( disable: 4702 ) // unreachable code, e.g. in <list> header.
#pragma warning( disable: 4710 ) // call was not inlined
#pragma warning( disable: 4711 ) // call was inlined
#pragma warning( disable: 4820 ) // some padding was added
#pragma warning( disable: 4917 ) // a GUID can only be associated with a class, interface or namespace
#pragma warning( disable: 4996 ) // MSVC 9: a C stdlib function has been "deprecated" (says MS)
I was trying to create a small define to work around this bug in QITABENT and I noticed peculiar behavior of the #pragma warning (disable: ...) statement.
In the following code the define QITABENT generates warning C4838
static const QITAB qit[] =
{
QITABENT(MediaPlayerCallback, IMFPMediaPlayerCallback)
};
I can easily suppress this warning, this works:
#pragma warning( push )
#pragma warning( disable: 4838 )
static const QITAB qit[] =
{
QITABENT(MediaPlayerCallback, IMFPMediaPlayerCallback)
//{ 0 },
};
return QISearch(this, qit, riid, ppv);
#pragma warning( pop )
Now I wanted to make a define QITABENTEX which automatically suppresses the warning generated by QITABENT. But it seems impossible because when I write the following code the warning C4838 is not suppressed.
static const QITAB qit[] =
{
#pragma warning( push )
#pragma warning( disable: 4838 )
QITABENT(MediaPlayerCallback, IMFPMediaPlayerCallback)
#pragma warning( pop )
//{ 0 },
};
How does the compiler interpret this code in such a way that the warning is not suppressed?
This probably has to with when the definition for QITABENT is fully resolved.
(Note that I'm not really interested in making the above code work, I'm just really curious how its interpreted by the compiler)
Addendum:
Regarding the close vote and clarification: I got into a discussion with someone giving a shotgun/link-only answer, presumably only reading the question halfway through (since the question explained how to use #pragma in a macro which is not what I'm asking) now that answer got (self) deleted and I got a close vote for being unclear. So let me reiterate my intentions with this question:
This question is not about finding a define to suppress this warning
This question is not about how to suppress a warning in VC++ in general
This question is about trying to understand what happens with the three lines of suppression code in the last code sample. Why do they not have effect in that exact position (in an array initialization) but do have effect outside the array initialization? This probably boils down to answering how and when the pragma statements and macross are resolved.
The initializer list terminates with the closing curly bracket }, and that is where warning is generated.
Try this:
static const QITAB qit[] =
{
QITABENT(Derived, Base)
#pragma warning( push )
#pragma warning( disable: 4365 )
}
#pragma warning( pop )
;
[edited]
Per Mr.C64's comment below, corrected the order of parameters in QITABENT(Derived, Base).
I'm trying to do something like this:
#ifdef _MSC_VER
#define DISABLE_WARNINGS() \
#pragma warning( push, 0 )
#elif __GNUC__
#define DISABLE_WARNINGS() \
#define DISABLE_WARNINGS \
#pragma GCC diagnostic push \
#pragma GCC diagnostic ignored "-Wall"
#endif
I would like to define a single macro such as "DISABLE_WARNINGS" in my code before including 3rd party headers that produce enormous amount of warnings on W4, and also ensure the code compiles on any platform.
For example:
DISABLE_WARNINGS
#include <gtkmm/buttonbox.h>
#include <gtkmm/box.h>
#include <gtkmm/window.h>
#include <gtkmm/button.h>
ENABLE_WARNINGS
What would be the best way to achieve this with single macro?
In C99 mode, you can use _Pragma instead of #pragma:
#define DISABLE_WARNINGS \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wall\"")
I have a class that is exported and it uses a header only structure as a member variable.
#include "SomeStruct.h"
class API_CLASS SomeClass
{
public:
// ...
private:
#pragma warning( push )
#pragma warning( disable: 4251 )
SomeStruct _active;
#pragma warning( pop )
};
I get warning 4251 as the structure is not exported. The structure is part of an external code and not a part of current scope.
I would like to make this code a bit more readable as this is a header I will distribute.
Ideally, I want the class to read
#include "SomeStruct.h"
class API_CLASS SomeClass
{
public:
// ...
private:
DISABLE_WARNING_BEGIN(4251)
SomeStruct _active;
DISABLE_WARNING_END
};
It may be more work to disable multiple warnings but if that can be done, then great but not necessary. The macro should result in code only for WIN32 environment. I have tried to write the macro but to include a '#' is beyond me.
I can live with this. This is better than what I have now.
#include "SomeStruct.h"
class API_CLASS SomeClass
{
public:
// ...
private:
#pragma warning(suppress: 4251)
SomeStruct _active;
};
Thanks to Heinirichj
To add #pragma into a MACRO, you may use:
__pragma with MSVC
_Pragma with gcc
See Pragma in define macro for more detail.
In my code, I am using an array xyz of 10 objects. When I am trying to access an element of the array using an unsigned int index like this: xyz[level], I get 'Buffer overrun' warning. Logically, I am pretty sure that level won't exceed 10. How to avoid this warning?
I'm probably teaching my grandmother to suck eggs here, but do remember that "level won't exceed 10" is wrong for an array of size 10:
char a[10];
a[10] = '\0'; // Bug, and "Buffer Overrun" warning.
Are you really sure? I never got this warning until now. So, double check.
Anyway, you can use the
#pragma warning( disable: 6386 )
preprocessor directive. I usually push and pop this to the "pragma stack"
#pragma warning( push )
#pragma warning( disable : 6386 )
// Some code
#pragma warning( pop )
as advised here.