在C/C++编译时按位运算
我想了解如何按位运算由C/C++编译器处理。 具体来说,我说的是用gcc编译的C,但我相信这个问题比这个更普遍一些。在C/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是否支持这种优化?
是,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
会的gcc编译时
我不知道你,我的的确
如何检查一个gcc是否支持这样的优化评估SOME_VALUE?
我用-S标志生成汇编代码,并检查它
movl $4, %esi
检查simurg的答案。你的编译器不会优化。它是预处理器。另外我不认为这个运营商想要开始一个关于这个问题的调查。 – Matthias 2017-02-23 08:16:46
你的编译器不知道SOME_VALUE
。 C代码首先通过C预处理器传递给C编译器。
gcc -E code.c
你会看到,输入到C编译器的真正的代码是:
int main(void) {
printf("Value: %lu#n", ((0x111UL) << (2)) & (7));
return 0;
}
因此问题变成了“是否可以通过运行gcc作为看到C预处理器的输出C编译器GCC优化((0x111UL) << (2)) & (7)
“,答案是肯定的(正如其他答复者通过查看生成的汇编代码证明的那样)。
谢谢!我已经接受了另一个答案,但你同样有帮助:) – kliteyn 2015-04-02 12:14:42
正如其他人回答,是的,它会。但是要考虑不是要求;如果你想确定这一点,只需预先计算它,因为你有所有的元素来做到这一点。
看看汇编语言输出(在gcc中有命令行选项 - '-S')。预处理器应该替换文本,因此编译器是否优化了剩余的内容。这应该。 – sje397 2015-04-02 07:59:49
这被称为“常量折叠”,您可以确信任何现代编译器都会在编译时执行此操作。 – Sneftel 2015-04-02 08:00:14
你可能想阅读§6。6(“常量表达式”)在ISO/IEC 9899:1999中解决了这个问题。或者[此概述](http://en.cppreference.com/w/c/language/constant_expression)。 – 2015-04-02 08:11:37