My project requirement is to have no warnings at all, treating them as errors, but third party tools generate their own warnings whose code I cannot access.
So I have to disable specific warnings before including the third-party headers:
#pragma warning( push )
#pragma warning( disable : 4005 ) // macro redefinition
#pragma warning( disable : 4505 ) // unreferenced local function has been removed
#include <cuda_runtime_api.h>
#pragma warning( pop )
This approach sometimes works, sometimes it does not, depending on the header file.
Could it be due to the fact that considering all the warnings as errors, #pragma warning does not apply?
Or could it be that inside the included code there are #pragmas that disable mine?
How can I suppress them?
P.S.: The program is built with the /WX (treat warnings as errors) Visual Studio flag. How can I disable it in some parts of the source code, especially for third-party code I include, with the preprocessor?
From experience with very similar issues (but with the in-built Windows 'system' headers, rather than 3rd-party stuff), I have reluctantly accepted the fact that the #pragma warning (push|pop)
system doesn't really work! This seems especially true when the "Enable all warnings" (/Wall
) option is set, as the #pragma warning(pop)
doesn't understand what 'level number' to restore.
The only workable technique I have (so far) come up with is to explicitly disable the relevant warnings before inclusion of the '3rd-Party' headers, then (again, explicitly) reset them afterwards. Here is a short extract from the "global" header (the one I use to generate the pre-compiled header) I use for building my projects:
// Turn off warnings generated by the "standard" and "MFC" header files. *** Note: using "#pragma(push, 2) ...
// #pragma(pop)" to embrace these header files doesn't work! *** [For some reason (possibly something weird in
// one of the headers), warnings such as 'unused parameters' and 'signed/unsigned' are not re-enabled.] ...
#pragma warning(disable:4091) // 'typedef' ignored on left of tagGPFIDL.
#pragma warning(disable:4191) // unsafe conversion to AFX_PMSG(W) (MMAP)
#pragma warning(disable:4239) // Non-standard: conv. <class> to &<class>
#pragma warning(disable:4251) // class 'XXX' needs to have dll-interface
#pragma warning(disable:4263) // member function does not override . ...
//... and around 30 or so other, similar lines.
#include <afxwin.h> // Minimal set of afx... (MFC) headers for the things we want to do ... (?)
#include <afxwinappex.h> // Required for the base application class: MFC's CWinAppEx
#include <afxmdiframewndex.h> // Base frame windows "CMDIFrameWndEx" and "CMDIChildWndEx"
#include <mmsystem.h> // Mulitmedia APIs: allows playing of sounds in various alert message boxes
#include <MsiQuery.h> // Required for DLL interface to the MSI installer (itself #includes msi.h)
//... and all other warning-prone headers ...
#pragma warning(default:4091) // 'typedef' ignored on left of tagGPFIDL.
#pragma warning(default:4191) // unsafe conversion to AFX_PMSG(W) (MMAP)
#pragma warning(default:4239) // Non-standard: conv. <class> to &<class>
#pragma warning(default:4251) // class 'XXX' needs to have dll-interface
#pragma warning(default:4263) // member function does not override . ...
//... and all the others corresponding to those that were disabled
Note that, by using the #pragma warning(default:nnnn)
(rather than #pragma warning(enable:nnnn)
) you are resetting the warning to the project's setting, rather than blindly enabling it.
I understand that this is rather clumsy - and, almost certainly, not what you are looking or - but it does work. Also, once you have established the basic list of warnings, it's a relatively low-maintenance solution.
PS: As far as I am aware, there is no option available to the MSVC
pre-processor to either detect or change the /WX
(treat warnings as errors) compiler option, although you can set this for any specific warning, with #pragma warning(error:nnnn)
, and 'unset' it using default
.
EDIT: Another possible way of disabling the following:
warning C4505: 'bar': unreferenced local function has been removed
is to actually reference the 'offending' function. But I'm not here being sarcastic - you can include a dummy static inline function that references bar
(in your header) and that will silence the warning (it isn't given for functions defined as static inline
). So, assuming the function bar
is defined (in the 3rd-party header) like this:
static int bar(int b)
{
return b * b;
}
but bar
is never referenced in (some of) your build units, then adding this line to your 'global' header (after the inclusion of the 3rd-party header) will kill the warning (for MSVC
, but not for clang-cl
):
static inline int foo(int a) { return bar(a); }
Of course, if there are many such warnings, this method could become a bit cumbersome; but again, once you have the code written, it's low-maintenance.