C/C++编译器是否会对可交换运算符(例如:+,*)重新排序以优化常量

Rob*_*Hsu 5 c++ optimization

请问以下代码的第2行

int bar;
int foo = bar * 3 * 5;
Run Code Online (Sandbox Code Playgroud)

被优化为

int bar;
int foo = bar * 15;
Run Code Online (Sandbox Code Playgroud)

甚至更多:

int foo = 3 * bar * 5;
Run Code Online (Sandbox Code Playgroud)

可以优化吗?

目的实际上是问我是否可以写

int foo = bar * 3 * 5;
Run Code Online (Sandbox Code Playgroud)

代替

int foo = bar * (3 * 5);
Run Code Online (Sandbox Code Playgroud)

保存括号.(并且减轻了手动操作那些常量排序的需要=>并且在许多情况下,使用相关变量的分组常量更有意义,而不是为了优化而分组常量)

Sha*_*ger 7

几乎所有编译器都会为整数执行此操作,因为即使常量崩溃可能以不同的方式溢出,标准也可能忽略溢出,因此他们可以按照自己喜欢的方式执行操作.

如果它遵循严格的浮点数学,它通常不适用于浮点值; 浮点数学的评估顺序会影响结果,因此严格的合规性不能重新排序浮点数学.

5.1.2.3程序执行

[#1]本国际标准中的语义描述描述了抽象机器的行为,其中优化问题无关紧要.

[#3]在抽象机器中,所有表达式都按语义指定进行计算.

[#13]示例5由于精度和范围的限制,浮点表达式的重排通常受到限制.即使在没有溢出和下溢的情况下,由于舍入误差,实现通常也不能应用加法或乘法的数学关联规则,也不能应用分布规则.(来源)

它没有准确地描述常量的使用,但是很明显注意到看似等效的操作在浮点运算的奇异世界中实际上并不等效(例如x / 5.0,不能被x * 0.2完全等价转换,x + x * y不能等效地表示为x * (1.0 + y)).

  • 浮点情况的一个例子:[为什么GCC不优化`a*a*a*a*a*a`到`(a*a*a)*(a*a*a)`?](http ://stackoverflow.com/q/6430448/995714) (2认同)