我的分号怎么了? (gcc 预处理器)
What happened to my semicolon? (gcc preprocessor)
我想我会很聪明,围绕 Disable/Enable 中断编写一个小的预处理器包装器,如下所示:
#define WITH_INTERRUPTS_DISABLED(_body) \
do { \
uint32_t primask = DisableGlobalIRQ(); \
do { \
_body \
} while (0); \
EnableGlobalIRQ(primask); \
} while (0)
GCC 预处理器,与此源一起出现时:
WITH_INTERRUPTS_DISABLED(
i += 2;
quux();
);
... 生成此输出(为了便于阅读而重新格式化):
do {
uint32_t primask = DisableGlobalIRQ();
do {
i += 2;
quux();
} while (0);
EnableGlobalIRQ(primask);
} while (0)
根据 Mr. Godbolt,所有 GCC 变体的行为都如上,省略了结束分号。同时,所有 clang
个变体的输出都包含分号。
有没有办法说服 GCC 包含分号?
分号没有任何问题,GCC 生成的很好。如果 GCC 和 clang 在这个基本的东西上有所不同,那将是非常令人吃惊的,这肯定是由 C 标准明确定义的,并且在实际代码中广泛使用。
但是Godbolt Compiler Explorer的默认设置会过滤掉它,可能是因为它看起来像汇编语言的注释。来自 interjay 的示例:https://godbolt.org/z/94e4q3ehK
如果您关闭“过滤器:评论”,您会看到分号在那里,前面有几个空行:https://godbolt.org/z/7n896or8Y
do { uint32_t primask = DisableGlobalIRQ(); do { i += 2; quux(); } while (0); EnableGlobalIRQ(primask); } while (0)
;
正如 interjay 指出的那样,Explorer 旨在显示汇编输出,而不是预处理的 C,因此 -E
是 not supported very well 也就不足为奇了。
clang 似乎省略了空行,我猜这是为了防止 Godbolt 认为它是评论:
do { uint32_t primask = DisableGlobalIRQ(); do { i += 2; quux(); } while (0); EnableGlobalIRQ(primask); } while (0);
我认为这种差异不存在任何合规性问题,因为两种情况下标记的顺序相同。
我想我会很聪明,围绕 Disable/Enable 中断编写一个小的预处理器包装器,如下所示:
#define WITH_INTERRUPTS_DISABLED(_body) \
do { \
uint32_t primask = DisableGlobalIRQ(); \
do { \
_body \
} while (0); \
EnableGlobalIRQ(primask); \
} while (0)
GCC 预处理器,与此源一起出现时:
WITH_INTERRUPTS_DISABLED(
i += 2;
quux();
);
... 生成此输出(为了便于阅读而重新格式化):
do {
uint32_t primask = DisableGlobalIRQ();
do {
i += 2;
quux();
} while (0);
EnableGlobalIRQ(primask);
} while (0)
根据 Mr. Godbolt,所有 GCC 变体的行为都如上,省略了结束分号。同时,所有 clang
个变体的输出都包含分号。
有没有办法说服 GCC 包含分号?
分号没有任何问题,GCC 生成的很好。如果 GCC 和 clang 在这个基本的东西上有所不同,那将是非常令人吃惊的,这肯定是由 C 标准明确定义的,并且在实际代码中广泛使用。
但是Godbolt Compiler Explorer的默认设置会过滤掉它,可能是因为它看起来像汇编语言的注释。来自 interjay 的示例:https://godbolt.org/z/94e4q3ehK
如果您关闭“过滤器:评论”,您会看到分号在那里,前面有几个空行:https://godbolt.org/z/7n896or8Y
do { uint32_t primask = DisableGlobalIRQ(); do { i += 2; quux(); } while (0); EnableGlobalIRQ(primask); } while (0)
;
正如 interjay 指出的那样,Explorer 旨在显示汇编输出,而不是预处理的 C,因此 -E
是 not supported very well 也就不足为奇了。
clang 似乎省略了空行,我猜这是为了防止 Godbolt 认为它是评论:
do { uint32_t primask = DisableGlobalIRQ(); do { i += 2; quux(); } while (0); EnableGlobalIRQ(primask); } while (0);
我认为这种差异不存在任何合规性问题,因为两种情况下标记的顺序相同。