我知道 #warning 指令不是标准的C /C++,但有几个编译器支持它,包括 gcc/g++。但是对于那些不支持它的人,他们会默默地忽略它还是会导致编译失败?换句话说,我可以在我的项目中安全地使用它而不破坏不支持它的编译器的构建吗?
6 回答
需要注意的是,MSVC 使用以下语法:
#pragma message ("你的警告文本在这里")
通常的#warning 语法会产生致命错误
C1021:无效的预处理器命令“警告”
所以它不能移植到那些编译器。
如果编译器不支持#warning,它很可能会发出错误。与#pragma 不同,不建议预处理器忽略它不理解的指令。
话虽如此,我已经在各种不同(相当常见的)平台上使用了编译器,它们都支持#warning。
即使代码块未包含在您的编译中,您也可能至少会从无法识别#warning 的编译器中收到无法识别的指令警告。这可能会或可能不会被视为错误 - 编译器可以合法地将其视为错误,但许多会更加宽松。
您是否知道(您能说出)提供#warning 的GCC/G++ 以外的编译器吗?[编辑: Sun Solaris 10 (Sparc) 和 Studio 11 C/C++ 编译器都接受#warning。]
我曾经在使用 Atmel 处理器的编译器时遇到过这个问题。由于未知的#warning 令牌,它确实产生了预处理器错误。
不幸的是,解决方案似乎是将整个源代码树转换为使用 #pragma 等效项,并接受如果使用 gcc 构建行为会有所不同。
从 mingw 切换到 Visual Studio 时,我将这些行添加到我的全局配置标题中。(将其包含在 stdafx.h 中)
#ifdef __GNUC__
//from https://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html
//Instead of put such pragma in code:
//#pragma GCC diagnostic ignored "-Wformat"
//use:
//PRAGMA_GCC(diagnostic ignored "-Wformat")
#define DO_PRAGMA(x) _Pragma (#x)
#define PRAGMA_GCC(x) DO_PRAGMA(GCC #x)
#define PRAGMA_MESSAGE(x) DO_PRAGMA(message #x)
#define PRAGMA_WARNING(x) DO_PRAGMA(warning #x)
#endif //__GNUC__
#ifdef _MSC_VER
/*
#define PRAGMA_OPTIMIZE_OFF __pragma(optimize("", off))
// These two lines are equivalent
#pragma optimize("", off)
PRAGMA_OPTIMIZE_OFF
*/
#define PRAGMA_GCC(x)
// https://support2.microsoft.com/kb/155196?wa=wsignin1.0
#define __STR2__(x) #x
#define __STR1__(x) __STR2__(x)
#define __PRAGMA_LOC__ __FILE__ "("__STR1__(__LINE__)") "
#define PRAGMA_WARNING(x) __pragma(message(__PRAGMA_LOC__ ": warning: " #x))
#define PRAGMA_MESSAGE(x) __pragma(message(__PRAGMA_LOC__ ": message : " #x))
#endif
//#pragma message "message quoted"
//#pragma message message unquoted
//#warning warning unquoted
//#warning "warning quoted"
PRAGMA_MESSAGE(PRAGMA_MESSAGE unquoted)
PRAGMA_MESSAGE("PRAGMA_MESSAGE quoted")
#warning "#pragma warning quoted"
PRAGMA_WARNING(PRAGMA_WARNING unquoted)
PRAGMA_WARNING("PRAGMA_WARNING quoted")
现在我使用 PRAGMA_WARNING(这需要修复)
遗憾的是 gcc 中没有#pragma warning
,因此它会警告未指定的编译指示。
我怀疑 gcc 会添加#pragma warning"
而不是 microsoft 添加#warning
。
实际上,我所知道的大多数编译器都会忽略未知的#pragma 指令,并输出一条警告消息——所以在最坏的情况下,你仍然会收到一条警告。