C/C++中的编译时按位运算

kli*_*eyn 3 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)

  static inline void foo() { printf("Value: %lu#n", SOME_VALUE); }
Run Code Online (Sandbox Code Playgroud)

SOME_VALUE的所有成分都是常量,它们在编译时都是已知的.

所以我的问题是:gcc会在编译时评估SOME_VALUE,还是仅在运行时完成? 如何检查gcc是否支持此类优化?

sim*_*urg 5

你的编译器不知道SOME_VALUE.C代码首先通过C预处理器传递给C编译器.您可以通过运行gcc来查看C预处理器的输出:

gcc -E code.c

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

int main(void) {
 printf("Value: %lu#n", ((0x111UL) << (2)) & (7));
 return 0;
}
Run Code Online (Sandbox Code Playgroud)

因此问题变成"GCC的C编译器是否优化((0x111UL) << (2)) & (7)",答案是肯定的(正如其他回答者通过查看生成的汇编代码证明的那样).


Bri*_*sey 4

是的,gcc 会对此进行优化,因为它是一个完全的常量表达式。

要检查这一点,请查看汇编代码,例如使用此工具https://gcc.godbolt.org/

#include <stdio.h>

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

void foo() { printf("Value: %lu#n", SOME_VALUE); }
Run Code Online (Sandbox Code Playgroud)

我必须稍微修改你的代码,否则 gcc 会优化整个事情并且什么也不留下!

.LC0:
    .string "Value: %lu#n"
foo():
    movl    $4, %esi
    movl    $.LC0, %edi
    xorl    %eax, %eax
    jmp printf
Run Code Online (Sandbox Code Playgroud)