咨询跨平台禁用C++废弃警告的方法(含itkLegacyMacro场景)
我最近在重构一个基于ITK的库,用itkLegacyMacro标记了一批旧方法,但单元测试还在依赖这些废弃接口,得找个能在多数编译器下通用的警告禁用办法。先看看这个宏的实现逻辑:
// Setup compile-time warnings for uses of deprecated methods if
// possible on this compiler.
#if defined( GNUC ) && !defined( __INTEL_COMPILER ) && ( GNUC >= 4 )define itkLegacyMacro(method) attribute((deprecated)) method#elif defined(_MSC_VER)
define itkLegacyMacro(method) __declspec(deprecated) method#else
define itkLegacyMacro(method) method#endif
从代码能看出来,它已经针对GCC和MSVC做了废弃标记的适配,那我们的禁用方案也得对应这两个主流编译器来做,同时尽量兼容其他编译器。
优先推荐:局部代码块禁用(不影响全局)
这种方式只会屏蔽指定代码段的废弃警告,不会漏掉其他地方的重要警告,是最安全的做法。
GCC/Clang 系列编译器:
用编译器的诊断指令包裹需要禁用警告的代码:#pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" // 这里放调用废弃方法的单元测试代码 auto myObj = MyITKClass::New(); myObj->OldDeprecatedMethod(); #pragma GCC diagnostic popClang完全兼容这套指令,直接用就行。
MSVC 编译器:
对应的警告码是4996,用同样的局部指令方式:#pragma warning(push) #pragma warning(disable : 4996) // 调用废弃方法的测试代码 auto myObj = MyITKClass::New(); myObj->OldDeprecatedMethod(); #pragma warning(pop)
更方便:封装跨编译器宏
如果单元测试里有很多地方要调用废弃方法,写一堆重复的编译指令太麻烦,可以封装成跨编译器的宏,用起来更简洁:
// 定义跨编译器的废弃警告禁用宏 #if defined(__GNUC__) || defined(__clang__) #define DISABLE_DEPRECATED_WARNINGS_BEGIN \ _Pragma("GCC diagnostic push") \ _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") #define DISABLE_DEPRECATED_WARNINGS_END \ _Pragma("GCC diagnostic pop") #elif defined(_MSC_VER) #define DISABLE_DEPRECATED_WARNINGS_BEGIN \ _Pragma("warning(push)") \ _Pragma("warning(disable : 4996)") #define DISABLE_DEPRECATED_WARNINGS_END \ _Pragma("warning(pop)") #else // 其他未适配的编译器,默认不做处理 #define DISABLE_DEPRECATED_WARNINGS_BEGIN #define DISABLE_DEPRECATED_WARNINGS_END #endif
之后在单元测试里就可以这样用:
DISABLE_DEPRECATED_WARNINGS_BEGIN TEST(MyClassTest, TestLegacyFunction) { auto obj = MyITKClass::New(); obj->LegacyMethod(); } TEST(MyClassTest, TestAnotherLegacyFunction) { auto obj = MyITKClass::New(); obj->AnotherLegacyMethod(); } DISABLE_DEPRECATED_WARNINGS_END
不推荐:全局禁用警告
如果实在要全局屏蔽这类警告(不建议,容易错过其他重要的废弃提示),可以在编译参数里加对应的选项:
- GCC/Clang:添加
-Wno-deprecated-declarations参数 - MSVC:添加
/wd4996参数
需要注意的是,这个方案完全对应itkLegacyMacro的实现,能准确屏蔽它触发的废弃警告,同时覆盖了当前主流的编译器,也兼容其他未适配的编译器(默认不做处理)。
内容的提问来源于stack exchange,提问作者Dženan

