fea*_*ool 3 c gcc preprocessor clang
我想我会很聪明,围绕禁用/启用中断编写一个小的预处理器包装器,如下所示:
#define WITH_INTERRUPTS_DISABLED(_body) \
do { \
uint32_t primask = DisableGlobalIRQ(); \
do { \
_body \
} while (0); \
EnableGlobalIRQ(primask); \
} while (0)
Run Code Online (Sandbox Code Playgroud)
GCC 预处理器,当出现此源时:
WITH_INTERRUPTS_DISABLED(
i += 2;
quux();
);
Run Code Online (Sandbox Code Playgroud)
...生成此输出(重新格式化以提高可读性):
do {
uint32_t primask = DisableGlobalIRQ();
do {
i += 2;
quux();
} while (0);
EnableGlobalIRQ(primask);
} while (0)
Run Code Online (Sandbox Code Playgroud)
根据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)
;
Run Code Online (Sandbox Code Playgroud)
作为interjay指出,在资源管理器的目的是显示组件的输出,没有预处理的C,所以它并不奇怪,-E是不支持的非常好。
似乎 clang 省略了空行,我猜这恰好是为了防止 Godbolt 认为这是一个评论:
do { uint32_t primask = DisableGlobalIRQ(); do { i += 2; quux(); } while (0); EnableGlobalIRQ(primask); } while (0);
Run Code Online (Sandbox Code Playgroud)
我认为这种差异没有任何合规性问题,因为在这两种情况下令牌的顺序是相同的。