是否会由预编译器评估bitshift和算术运算?

时间:2016-08-03 20:21:00

标签: c++ precompile

如果我在C ++ 98程序中定义以下内容:

#define BITS_PER_FOO 2
#define BITS_PER_BAR 3
#define FOOBARS (1<<(BITS_PER_FOO*BITS_PER_BAR))

那么预编译器会将FOOBARS评估为64吗?或者我会在代码中使用FOOBARS的每个位置进行乘法和位移操作?

3 个答案:

答案 0 :(得分:2)

不,因为它不是预处理器的业务。它通常是替换物,而不是不断的折叠。

但是,任何合理的编译器都会进行常量折叠,因此您不应期望这与在运行时执行的指令相对应。

答案 1 :(得分:2)

预编译器只进行文本替换 - 它本质上是复制和放大器。粘贴类固醇。这意味着您为FOOBAR编写的表达式将在每个替换位置完全展开。

现在,任何体面的编译器都会在编译时评估整个子表达式。但是,你可以保存一些工作(并且有一些额外的好处,比如有一个清晰的表达类型,更清晰的诊断,更少的错误来自错误的地方的替换,并且有一个实际的左值而不是表达式)将这些值定义为实际常量,如:

const int bits_per_foo = 2;
const int bits_per_bar = 3;
const int foobars = 1<<(bits_per_foo*bits_per_bar);

答案 2 :(得分:0)

乘法和位移操作将在您使用FOOBARS的每个位置进行。

请参阅:#define Directive (C/C++)

#define形成一个宏,意味着标识符被token-string中的所有内容替换。在您的情况下,预处理器将FOOBARS的实例替换为表达式(1<<(BITS_PER_FOO*BITS_PER_BAR))