有可能有代码在任何地方都可以工作,并发出自定义
许多编译器上的警告,包括大多数编译器人们可能
使用(GCC,clang,MSVC,Intel,...)。
首先,我们应该区分警告和信息
消息。我认为唯一有意义的是,如果你
编译时带有致命警告(例如,在 GCC 上为 -Werror),警告
应该导致编译失败,而信息性消息
不应该。
正如原始问题所述,MSVC 9.0+ 支持
#pragma message("Hello")
尽管有(恕我直言,不幸的)名字,MSVC 会在这里发出警告,
不是信息性消息。 AFAICT 没有办法发出
信息性消息。
GCC 4.8+ 和 Intel 支持警告消息编译指示,这意味着我们可以
使用预处理器生成它们:
#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 开始,此类警告实际上是信息性的(我已经
提交了一个错误)。我不确定何时添加了支持,但 clang 的版本
无论如何数字都非常无用(感谢Apple将它们设置为
在他们的铿锵声中完全不同的东西
分配)。不幸的是,没有__has_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 回购而不是这个答案,因为我更有可能保持最新。