C编译器是否允许优化冗余语句?

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)

Lun*_*din 6

C标准说(C11 5.1.2.3/4):

在抽象机器中,所有表达式都按语义指定进行计算.实际实现不需要评估表达式的一部分,如果它可以推断出它的值未被使用并且不产生所需的副作用(包括由调用函数或访问易失性对象引起的任何副作用).

因此编译器可以自由地优化函数调用,除非函数包含任何"需要的"副作用.措辞有点模糊,可能以不同的方式解释.但实际上,所有编译器都很可能优化掉空函数.


rac*_*man 5

上世纪80年代,我的一个朋友告诉我他编写了一个程序,该程序执行一种算法来计算pi,然后将其打印出来。

当他查看编译的exe文件时,很惊讶地看到编译器基本上生成了:输出3.14159

简而言之,允许C(或任何其他语言)编译器执行任何不改变程序行为的操作。

这也适用于Java等,其中JVM采用了多种技术来提高速度(例如,“展开”循环,以便按顺序执行代码而无需经历循环开销等)。