c++ - 编译器是否将给定常量参数的简单函数简化为唯一指令?

标签 c++ c gcc optimization compiler-optimization

我一直认为这是真的,但从未得到任何验证。考虑一个非常简单的函数:

int subtractFive(int num) {
    return num -5;
}

如果对该函数的调用使用编译时常量,例如

  getElement(5);

打开优化的编译器很可能会内联它。然而,我不清楚的是,如果 num - 5 将在运行时或编译时进行评估。表达式简化会以这种方式通过内联函数递归扩展吗?还是不超越功能?

最佳答案

我们可以简单的看一下生成的程序集就知道了。这段代码:

int subtractFive(int num) {
    return num -5;
}

int main(int argc, char *argv[]) {
  return subtractFive(argc);
}

g++ -O2 编译产生

leal    -5(%rdi), %eax
ret

所以函数调用确实被简化为一条指令。这种优化技术称为 inlining .

当然,我们可以使用相同的技术来查看编译器的处理能力,例如稍微复杂一些

int subtractFive(int num) {
    return num -5;
}

int foo(int i) {
    return subtractFive(i) * 5;
}

int main(int argc, char *argv[]) {
  return foo(argc);
}

仍然被编译为

leal    -25(%rdi,%rdi,4), %eax
ret

所以这两个函数在编译时就被删除了。如果 foo 的输入在编译时已知,函数调用将(在本例中)简单地替换为编译时生成的常量 (Live)。

编译器还可以将此内联与常量折叠结合起来,如果所有参数都是编译时常量,则用函数调用的完全计算结果替换函数调用。例如,

int subtractFive(int num) {
    return num -5;
}

int foo(int i) {
    return subtractFive(i) * 5;
}

int main() {
  return foo(7);
}

编译为

mov     eax, 10
ret

相当于

int main () {
    return 10;
}

编译器总是会在它认为是个好主意的地方这样做,而且它(通常)在优化这个低级别的代码方面比你做得更好。

关于c++ - 编译器是否将给定常量参数的简单函数简化为唯一指令?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31501649/

相关文章:

c++ - 在qt中,我如何实现一个与代码中的变量保持一致的小部件

c++ - sscanf 解析方括号内的值

c - 如何从c中的输入文件读取结构信息

c++ - 按下键或移动鼠标时游戏速度变慢

c++ - C++ 中类似 Java 的 lastIndexOf

c++ - 在 C 中奇怪的类型转换好奇心

python - 如何制作一个用CFFI包裹的C-DLL来回调python

c++ - 使用 GCC 在可执行文件中嵌入资源

c - 在 Linux 上使用 gcc 并在 Windows 上使用 MinGW 构建共享库

c - GCC:将结构归零