如何禁用在 third-party 代码中获取 re-enabled 的警告?

How to disable a warning which gets re-enabled in third-party code?

我的项目要求是完全没有警告,将它们视为错误,但第三方工具会生成自己的警告,我无法访问其代码。

所以我必须在包含 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 )

此方法有时有效,有时无效,具体取决于 header 文件。

会不会是因为把所有的警告都当成错误,#pragma warning 不适用?

或者可能是在包含的代码中有#pragmas 禁用了我的代码?

如何抑制它们?

P.S.: 该程序是使用 /WX(将警告视为错误)Visual Studio 标志构建的。我怎样才能在源代码的某些部分禁用它,特别是对于我包含的 third-party 代码,预处理器?

根据非常相似问题的经验(但使用 in-built Windows 'system' headers,而不是第 3 方的东西),我有 很不情愿地接受了#pragma warning (push|pop)系统不能正常工作的事实!当设置了 "Enable all warnings" (/Wall) 选项时,这似乎 尤其是 正确,因为 #pragma warning(pop) 不理解 'level number' 的含义恢复。

我(到目前为止)想出的唯一可行技术是显式在包含'之前禁用相关警告3rd-Party' headers,然后(再次,明确地)之后重置它们。这是 "global" header(我用来生成 pre-compiled header 的一个简短摘录)我用于构建我的项目:

// 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

请注意,通过使用 #pragma warning(default:nnnn)(而不是 #pragma warning(enable:nnnn)),您会将警告重置为 项目的设置,而不是盲目地 启用它。

我知道这很笨拙 - 而且几乎可以肯定,这不是你正在寻找的或 - 但它 确实 有效。此外,一旦您建立了基本的警告列表,它就是一个相对 low-maintenance 的解决方案。

PS:据我所知,MSVC pre-processor 没有可用的选项来检测或更改 /WX(将警告视为errors) 编译器选项,虽然你可以为任何 specific 警告设置它,使用 #pragma warning(error:nnnn),'unset' 它使用 default.


编辑: 另一种禁用以下功能的可能方法:

warning C4505: 'bar': unreferenced local function has been removed

实际上是引用 'offending'函数。但我不是在这里讽刺 - 你可以包括一个虚拟 static inline 函数,它引用 bar (在你的 header 中)并且这将使警告静音(对于定义为 static inline 的函数不提供它。因此,假设函数 bar 是这样定义的(在第 3 方 header 中):

static int bar(int b)
{
    return b * b;
}

但是 bar 从未在您的(某些)构建单元中被引用,然后将此行添加到您的 'global' header(在包含第 3 方 header) 将终止警告(对于 MSVC,但对于 clang-cl 则不会):

static inline int foo(int a) { return bar(a); }

当然,如果有很多这样的警告,这个方法可能会变得有点麻烦;但是同样,一旦您编写了代码,它就是 low-maintenance.