msvc和gcc上的用户警告?

msvc和gcc上的用户警告?,gcc,visual-c++,user-warning,Gcc,Visual C++,User Warning,在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)) 我也是 #pragm

在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)
GCC有:

#warning(my warning here)
然而,当MSVC(2003)看到
#warning
并给出“致命错误C1021:无效的预处理器命令‘warning’”时,它抛出了一个错误


我能做些什么?有没有办法让GCC识别MSVC警告或MSVC不对GCC警告抛出错误?有什么我可以做的,这两个都可以吗?我可以让GCC警告我未知的pragma,但这不是最理想的解决方案

正如您现在发现的那样,
#warning
不是标准功能,因此您不能将其用于不支持它的编译器。如果您希望代码跨平台工作,则根本不会使用
#warning
——或者至少不会在MSVC打算处理的代码中使用(它可以由
#ifdef
或等效程序预处理)。因此:

但是,这重复了这个信息,我相信你已经考虑过不要这样做了——而且它是笨重的;你只会很少使用它。您可能还需要处理GCC以外的其他编译器(我对MSVC不够熟悉,不知道如何可靠地识别它)

如果
#警告
标准化,那就太好了;它在C99中没有标准化

(很久以前,有一个关于可以添加到C和
#warning
中的特性的问题。)

另请参见:

使用#if语句保护它们。查找由一个编译器定义而不是另一个编译器定义的符号

#ifdef _MSC_VER
#pragma NOTE(my warning here)
#else
#warning(my warning here)
#endif

有点难看,但我看不到其他方法。

我找到的解决此问题的最佳方法是在公共标题中包含以下内容:

// 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")
在整个代码中,而不是#警告

在MSVC下,您将收到如下消息:

c:\programming\some_file.cpp(3) : WARNING: your warning message here
#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
在gcc下,您将获得:

c:\programming\some_file.cpp:25: note: #pragma message: WARNING: your warning message here

不是十全十美,而是一种合理的折衷。

如果您愿意,您可以在前面的解决方案中添加一点内容(
#pragma warning
) 您的
#pragma消息

#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()
的情况下

例如,警告的形式太安静(当然对我来说)


然而,只有一小部分化妆品。

有可能在任何地方都能使用代码,并发出定制的声音 许多编译器上的警告,包括大多数编译器上的警告 使用(GCC、clang、MSVC、英特尔等)

首先,我们应该区分警告和信息 信息。我认为唯一有意义的是,如果你 编译时带有致命警告(例如GCC上的
-Werror
),警告 应导致编译失败,而信息性消息 不应该

正如原始问题所提到的,MSVC 9.0+支持

#pragma message("Hello")
尽管名字很不幸,MSVC会在这里发出警告, 不是信息性的消息。因为没有办法发出声音 信息性消息

GCC 4.8+和Intel支持警告消息pragmas,这意味着我们可以 使用预处理器生成它们:

#pragma GCC warning "Hello"
请注意,从版本18开始,PGI不支持此类警告,甚至 尽管pgc++伪装成GCC的一个版本 将
\uuuuu GNUC\uuuuuu
\uuuuu GNUC\uuu MINOR\uuuuuuu
设置为
表示GCC>=4.8)。他们是
问题的关键。在允许未来的情况下解决这个问题
版本的PGI,它确实支持那些正常工作,你可以这样做
比如:

#if defined(__PGI)
#  pragma diag_suppress 1675
#endif
不幸的是,我认为没有办法按下/弹出警告 用于PGI的堆栈,因此如果执行此操作,所有后续未知杂注都将 默默地被忽视。另外,请记住,
#pragma消息
是 被PGI悄悄忽略(它甚至不会生成有关 布拉格语未知)

Clang还支持
#pragma GCC warning
(以及
#pragma Clang
…
),但从6.0开始,这些警告实际上是信息性的(我已经 提交了一个bug)。我不知道什么时候增加了支持,但是clang的版本 不管怎么说,数字都是毫无用处的(多亏了苹果将其设置为 他们的叮当声完全不同 分发)。不幸的是,没有功能测试 宏,但我们可以暂时禁用未知的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:

#pragma _CRI message "Hello"
我实际上没有访问克雷编译器的权限,所以我不能确定 关于它是信息性的还是警告性的。如果有人知道 安瑟,请评论

总而言之,我最近在 要处理这个问题,当前的 版本如下所示:

c:\programming\some_file.cpp(3) : WARNING: your warning message here
#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回购协议,而不是此答案,因为我更有可能使其保持最新状态。

您在我停止编辑答案并添加反向测试时添加了此选项。。。我猜
\u MSC\u VER
\u GNUC\u
的对应物!谢谢。MyScver不仅声明你在微软C++中,而且还定义了你使用的版本。MaBDLAST似乎不适合我,但是我想补充的是,如果你只支持兼容C99和VS2008 +的GCC版本,你可以使用GCC的“Ay-PrAPMA关键字”(EX:<代码>和MSVC的uu pragma关键字(例如:
uu pragma(message(FILE\u LINE\u LINK“WARNING:”exp))
)将其进一步缩短。我假设VS2008是支持的最低版本,因为这是包含引用此关键字的文档的版本