我有一个代码,它使用#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
期望一个带括号的字符串。
我能做些什么来很好地抽象出来吗?
答案 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_I
。 X
的定义会对其进行整理,为WARNING_I
制作正确的S
。
答案 1 :(得分:0)
来自https://gcc.gnu.org/onlinedocs/gcc-6.3.0/cpp/Diagnostics.html#Diagnostics
'#error'和'#warning'都没有扩大其论点。内部空白序列每个都用一个空格替换。该行必须包含完整的令牌。最明智的做法是使这些指令的参数为单个字符串常量;这避免了撇号等问题。