有条件地使用#warning或#pragma消息或什么都没有

时间:2017-05-04 15:41:09

标签: c-preprocessor

我有一个代码,它使用#warning来向用户发送编译时间分支。代码有很多配置选项,因此不清楚代码的哪些部分实际进入编译。

一旦选择了配置选项,那些警告就会使输出混乱。所以我希望能够禁用它们。最简单的方法是将每个警告包装到#ifdef ... #else构造中。但是,如果我再次触摸该代码,我需要再次浏览整个代码库。

所以我想抽象一点。但是,我很难尝试定义一个调用#warning#pragma message的宏。以下编译但不做正确的事情:

#ifdef EMIT_WARNINGS
#define WARNING(s) _Pragma("message(\"Hi\")")
#else
#define WARNING(s)
#endif

WARNING("How can I print this?")

我将s放入其中的所有尝试都失败了。一旦我做_Pragma("message(\"" s "\")"),我得到_Pragma期望一个带括号的字符串。

我能做些什么来很好地抽象出来吗?

2 个答案:

答案 0 :(得分:1)

我所有把s放进去的尝试都失败了。一旦我做_Pragma("消息(\"" s" \")"),我得到_Pragma期望一个带括号的字符串。

_Pragma(S)的效果相当于#pragma X,其中X是S的 unstringified 形式。向后看,这意味着要获得{{1}的效果在#pragma X调用中,您只需 stringify X。

X的一部分本身就是一个字符串这一事实误导了你......不要将这些视为你正在组装的部分,而是作为一个整体。而不是尝试将_Pragma字符串化并将其放在s"message(\""中,而只是将"\")"本身整合为字符串,如下所示:

message(s)

因此,当启用警告时,#ifdef EMIT_WARNINGS #define WARNING_I(s) _Pragma(#s) #define WARNING(s) WARNING_I(message(s)) #else #define WARNING(s) #endif WARNING("How can I print this?") 会扩展为WARNING("How can I print this?")WARNING_I(message("How can I print this"))的这个论点本身就是你在pragma线上的意思;这是你的WARNING_IX的定义会对其进行整理,为WARNING_I制作正确的S

答案 1 :(得分:0)

来自https://gcc.gnu.org/onlinedocs/gcc-6.3.0/cpp/Diagnostics.html#Diagnostics

  

'#error'和'#warning'都没有扩大其论点。内部空白序列每个都用一个空格替换。该行必须包含完整的令牌。最明智的做法是使这些指令的参数为单个字符串常量;这避免了撇号等问题。