C/C++;

C/C++;,c,gcc,bit-manipulation,bit,C,Gcc,Bit Manipulation,Bit,我试图理解C/C++编译器是如何处理逐位操作的。 具体地说,我说的是用gcc编译的C,但我相信这个问题比这更一般 无论如何,假设我有一个宏定义如下: #define SOME_CONSTANT 0x111UL #define SOME_OFFSET 2 #define SOME_MASK 7 #define SOME_VALUE ((SOME_CONSTANT) << (SOME_OFFSET)) & (SOME_MASK) stati

我试图理解C/C++编译器是如何处理逐位操作的。 具体地说,我说的是用gcc编译的C,但我相信这个问题比这更一般

无论如何,假设我有一个宏定义如下:

  #define SOME_CONSTANT 0x111UL
  #define SOME_OFFSET   2
  #define SOME_MASK     7
  #define SOME_VALUE    ((SOME_CONSTANT) << (SOME_OFFSET)) & (SOME_MASK)

  static inline void foo() { printf("Value: %lu#n", SOME_VALUE); }
#定义一些常数0x111UL
#定义一些偏移量2
#定义一些遮罩7
#定义某个_值((某个_常量)
gcc会在编译时计算一些_值吗

我不知道你的,我的知道

如何检查gcc是否支持此类优化

我使用-S标志生成汇编代码并检查了它

    movl    $4, %esi

是的,gcc将对此进行优化,因为它是一个完全恒定的表达式

要检查这一点,请查看汇编代码,例如使用此工具


您的编译器不知道
某些\u值
。C代码首先通过C预处理器传递给C编译器。您可以通过运行gcc查看C预处理器的输出,如下所示:

gcc-E code.c

您将看到,提供给C编译器的真正代码是:

int main(void) {
 printf("Value: %lu#n", ((0x111UL) << (2)) & (7));
 return 0;
}
int main(无效){

PrtTf(“值:%Lux*n”),((0x111UL)

其他人已经回答了,是的,它会的。但是确实认为这不是必需的;如果你想确定这一点,就预先计算它,因为你有所有的元素去做它。

查看汇编语言输出(有命令行选项,将在GCC -'-s中这样做)。预处理器应该只替换文本,因此这取决于编译器是否优化剩余内容。它应该。这被称为“常量折叠”,您可以确信任何现代编译器都会在编译时执行此操作。您可能想阅读§6.6(“常量表达式”)在ISO/IEC 9899:1999中,哪个解决了这个问题。或者。@Sneftel re.“现代编译器”:1975是否有否决权的动机?当然,编译器不需要优化,但为什么它会选择不优化,除非它被指示(
-O0
)?考虑到常数折叠是可用的最基本的优化之一?在许多情况下,编译器由于外部因素(如低端硬件)而无法优化。当然,优化,不管简单与否,都必须实施,而且,同样,遵循“似乎”规则,您可能会决定应用一些。如果您编写了编译器,常量折叠会是您的首要关注点吗?@black是的,会。常量折叠在标头和标准库中使用得如此广泛,不实施它将是愚蠢的。更不用说,正确实现C需要在编译时计算常量整数表达式;否则您无法确定数组大小。@el.pescado IIRC,即使在
-O0
,GCC上也启用了常量折叠。谢谢!我已经接受了另一个答案,但您的答案同样有用:)检查simurg的答案。你的编译器没有优化。它是预处理器。我也不认为op想就这个问题进行民意调查。
.LC0:
    .string "Value: %lu#n"
foo():
    movl    $4, %esi
    movl    $.LC0, %edi
    xorl    %eax, %eax
    jmp printf
int main(void) {
 printf("Value: %lu#n", ((0x111UL) << (2)) & (7));
 return 0;
}