在MSVC中我有一个标题:
#define STR(x) #x
#define STR2(x) STR(x)
#define NOTE(text) message (__FILE__ "(" STR2(__LINE__) ") : -NOTE- " #text)
#define noteMacro(text) message (__FILE__ "(" STR2(__LINE__) ") : " STR2(text))
我做了
#pragma NOTE(my warning here)
海湾合作委员会有:
#warning(my warning here)
然而,当MSVC(2003)看到#warning
并且给出“致命错误C1021:无效的预处理器命令'警告'时,它会抛出一个拟合”
我该怎么办?有没有办法让GCC认出MSVC警告或MSVC不会在GCC警告上抛出错误?我可以做些什么对两者都有效吗?我可以让GCC警告我关于未知的pragma,但这不是最理想的解决方案。
答案 0 :(得分:15)
我发现此问题的最佳解决方案是在公共标题中包含以下内容:
// compiler_warning.h
#define STRINGISE_IMPL(x) #x
#define STRINGISE(x) STRINGISE_IMPL(x)
// Use: #pragma message WARN("My message")
#if _MSC_VER
# define FILE_LINE_LINK __FILE__ "(" STRINGISE(__LINE__) ") : "
# define WARN(exp) (FILE_LINE_LINK "WARNING: " exp)
#else//__GNUC__ - may need other defines for different compilers
# define WARN(exp) ("WARNING: " exp)
#endif
然后使用
#pragma message WARN("your warning message here")
整个代码中的而不是#warning
在MSVC下你会收到这样的消息:
c:\programming\some_file.cpp(3) : WARNING: your warning message here
在gcc下你会得到:
c:\programming\some_file.cpp:25: note: #pragma message: WARNING: your warning message here
不完美,但是合理的妥协。
答案 1 :(得分:6)
正如您现在发现的那样,#warning
不是标准功能,因此您不能将其用于不支持它的编译器。如果您希望代码跨平台工作,则根本不会使用#warning
- 或者至少不会使用MSVC要处理的代码(可以由#ifdef
预处理或同等学历)。因此:
#ifdef __GNUC__
#warning(warning message)
#else
#pragma NOTE(warning message)
#endif
但是重复了这个信息,我确信你不记得这样做 - 而且它很笨重;你很少使用它。您可能还需要处理除GCC之外的其他编译器(我对MSVC不够熟悉,不知道如何可靠地识别它)。
如果#warning
标准化会很好;它在C99中没有标准化。
(很长一段时间以前,有关此类功能的SO问题可以添加到C和#warning
。)
答案 2 :(得分:3)
用#if语句保护它们。查找由一个编译器定义的符号,而不是另一个编译器定义的符号。
#ifdef _MSC_VER
#pragma NOTE(my warning here)
#else
#warning(my warning here)
#endif
有点难看,但我没有看到另一种方式。
答案 3 :(得分:1)
如果您愿意,可以在上面的解决方案中添加一些小东西(#pragma warning
)
你的#pragma message
:
#pragma warning()
#pragma message(" SOME USER WARNING - FILE LINE etc... ")
这个小插件会生成真正的警告,并且在VC的窗口中看起来并不坏。 例如:
1>e:\proj\file.h(19) : warning C4615: #pragma warning : unknown user warning type
1> SOME USER WARNING - FILE LINE etc...
1>proj - 0 error(s), 1 warning(s)
通常我使用此方法警告并不太安静,例如没有#pragma warning()
的案例代码。
例如,警告的形式太安静了(当然对我来说)。
1> SOME USER WARNING - FILE LINE etc..
1>proj - 0 error(s), 0 warning(s)
然而,只有一个小化妆品。
答案 4 :(得分:0)
可能有代码可以在任何地方工作,并发出自定义 许多编译器的警告,包括大多数编译人员都可能 使用(GCC,clang,MSVC,Intel,......)。
首先,我们应该区分警告和信息
消息。我认为唯一有意义的是,如果你
使用致命警告编译(例如,GCC上的-Werror
),警告
应该导致编译失败,而信息消息
不该'吨
正如最初的问题所提到的,MSVC 9.0+支持
#pragma message("Hello")
尽管(恕我直言,不幸)名字,MSVC将在这里发出警告, 不是信息性的消息。 AFAICT没有办法发出一个 信息性消息。
GCC 4.8+和英特尔支持警告消息编译指示,这意味着我们可以 使用预处理器生成它们:
#pragma GCC warning "Hello"
请注意,从版本18开始,PGI甚至不支持此类警告
虽然pgc ++伪装成GCC的一个版本(即它)
将__GNUC__
,__GNUC_MINOR__
和__GNUC_PATCHLEVEL__
设置为值
表示GCC> = 4.8)。他们是
aware
这个问题。绕过这个,同时仍然允许一些未来
支持那些正常工作的PGI版本,你可以做到
类似的东西:
#if defined(__PGI)
# pragma diag_suppress 1675
#endif
不幸的是,我认为没有办法推送/弹出警告
PGI的堆栈,所以如果你这样做,所有后续的未知编译指示都会
被默默地忽略。另外,请记住#pragma message
是
PGI默默地忽略了它(它甚至不会产生警告
pragma未知)。
Clang还支持#pragma GCC warning
(以及#pragma clang
...
),但从6.0开始,此类警告实际上是信息性的(我已经提供了信息)
提交了一个错误)。我不确定何时添加支持,但是铿锵的版本
无论如何,数字都是无用的(感谢Apple将它们设置为
他们的铿锵声完全不同
分配)。遗憾的是,没有__has_pragma
功能测试
宏,但我们可以暂时禁用未知的编译指示警告
如果编译器不支持pragma,它将是静默的
忽略而不是发出不需要的警告:
#if defined(__has_warning)
# if __has_warning("-Wunknown-pragmas")
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wunknown-pragmas"
# pragma message "Hello"
# pragma clang warning "Hello"
# pragma clang diagnostic pop
# endif
#endif
当然,这很难看,但至少我们可以把它隐藏在宏观背后。
Cray 5.0+也有消息的编译指示:
#pragma _CRI message "Hello"
我实际上无法访问Cray的编译器,所以我无法确定 关于它是信息还是警告。如果有人知道 anwser,请评论!
总而言之,我最近添加了一些宏 Hedley处理这个问题,目前 版本看起来像这样:
#if HEDLEY_HAS_WARNING("-Wunknown-pragmas")
# define HEDLEY_MESSAGE(msg) \
HEDLEY_DIAGNOSTIC_PUSH \
_Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"") \
HEDLEY_PRAGMA(message msg) \
HEDLEY_DIAGNOSTIC_POP
#elif \
HEDLEY_GNUC_VERSION_CHECK(4,4,0) || \
HEDLEY_INTEL_VERSION_CHECK(16,0,0)
# define HEDLEY_MESSAGE(msg) HEDLEY_PRAGMA(message msg)
#elif HEDLEY_CRAY_VERSION_CHECK(5,0,0)
# DEFINE HEDLEY_MESSAGE(msg) HEDLEY_PRAGMA(_CRI message msg)
#else
# define HEDLEY_MESSAGE(msg)
#endif
#if HEDLEY_HAS_WARNING("-Wunknown-pragmas")
# define HEDLEY_WARNING(msg) \
HEDLEY_DIAGNOSTIC_PUSH \
_Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"") \
HEDLEY_PRAGMA(clang warning msg) \
HEDLEY_DIAGNOSTIC_POP
#elif \
(HEDLEY_GNUC_VERSION_CHECK(4,8,0) && !defined(__PGI)) || \
HEDLEY_INTEL_VERSION_CHECK(16,0,0)
# define HEDLEY_WARNING(msg) HEDLEY_PRAGMA(GCC warning msg)
#elif HEDLEY_MSVC_VERSION_CHECK(15,0,0)
# define HEDLEY_WARNING(msg) HEDLEY_PRAGMA(message(msg))
#else
# define HEDLEY_WARNING(msg) HEDLEY_MESSAGE(msg)
#endif
如果您不想使用Hedley(它只是一个公共域/ CC0标题),您可以毫不费力地替换内部宏。如果你这样做,我建议你把你的端口基于Hedley仓库而不是这个答案,因为我更有可能让它保持最新。