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

时间:2015-04-02 07:56:45

标签: 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); }

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

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

4 个答案:

答案 0 :(得分:5)

您的编译器不了解SOME_VALUE。 C代码首先通过C预处理器传递给C编译器。您可以通过运行gcc as:

来查看C预处理器的输出

gcc -E code.c

你会看到输入C编译器的真实代码是:

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

所以问题变成“GCC的C编译器是否优化((0x111UL) << (2)) & (7)”,答案是肯定的(正如其他通过查看生成的汇编代码证明了这一点的回答者所表明的那样)。

答案 1 :(得分:3)

是的,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); }

我不得不稍微修改你的代码,否则gcc会优化整个事情而不留下任何东西!

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

答案 2 :(得分:1)

  

将在编译时gcc评估SOME_VALUE

我不了解你的,我的

  

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

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

    movl    $4, %esi

答案 3 :(得分:-2)

正如其他人已经回答的那样,是的,它会。但要考虑那不是 required ;如果你想要确定性,那就预先计算它,因为你拥有所有要素。