Pac*_*ier 2 c compiler-optimization
C中有许多语句什么都不做.这意味着删除它们将在程序行为中没有可观察到的变化.
根据C标准,C编译器是否允许优化这些冗余语句?
例如,如果我们有这样的代码:
#include <stdio.h>
void f(void);
int main(void){
printf("a");
f(); // function call statement that provably does nothing
printf("b");
1000; // redundant expression statement
printf("c");
; // null statement
printf("d");
int x = 1; // assignment statement that is not used
printf("e");
return 0;
}
void f(void){
1000; // redundant expression statement
; // null statement
int x = 1; // assignment statement that is not used
}
Run Code Online (Sandbox Code Playgroud)
是否允许编译器生成与下面相同的目标代码?:
#include <stdio.h>
void f(void);
int main(void){
printf("a");
printf("b");
printf("c");
printf("d");
printf("e");
return 0;
}
void f(void){
}
Run Code Online (Sandbox Code Playgroud)
C标准说(C11 5.1.2.3/4):
在抽象机器中,所有表达式都按语义指定进行计算.实际实现不需要评估表达式的一部分,如果它可以推断出它的值未被使用并且不产生所需的副作用(包括由调用函数或访问易失性对象引起的任何副作用).
因此编译器可以自由地优化函数调用,除非函数包含任何"需要的"副作用.措辞有点模糊,可能以不同的方式解释.但实际上,所有编译器都很可能优化掉空函数.
上世纪80年代,我的一个朋友告诉我他编写了一个程序,该程序执行一种算法来计算pi,然后将其打印出来。
当他查看编译的exe文件时,很惊讶地看到编译器基本上生成了:输出3.14159
简而言之,允许C(或任何其他语言)编译器执行任何不改变程序行为的操作。
这也适用于Java等,其中JVM采用了多种技术来提高速度(例如,“展开”循环,以便按顺序执行代码而无需经历循环开销等)。