我的分号怎么了?(gcc预处理器)

我想我会很聪明,围绕禁用/启用中断编写一个小的预处理器包装器,如下所示:

#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)

根据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指出,在资源管理器的目的是显示组件的输出,没有预处理的C,所以它并不奇怪,-E是不支持的非常好。

似乎 clang 省略了空行,我猜这恰好是为了防止 Godbolt 认为这是一个评论:

  do { uint32_t primask = DisableGlobalIRQ(); do { i += 2; quux(); } while (0); EnableGlobalIRQ(primask); } while (0);

我认为这种差异没有任何合规性问题,因为在这两种情况下令牌的顺序是相同的。

  • @cigien: Several important points came from interjay's comments so I didn't feel I should earn reputation for it. This is a common practice on some of the other SE sites I use, maybe not here? Shrug.

以上是我的分号怎么了?(gcc预处理器)的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>