C/C++ 编译器优化:我应该更喜欢创建新变量、重用现有变量还是完全避免使用变量?

C/C++ compiler optimisations: should I prefer creating new variables, re-using existing ones, or avoiding variables altogether?

这是我一直想知道的事情:编译器是否更容易优化重新使用现有变量、创建新(理想情况下 const)中间变量或创建变量的函数避免直接使用表达式?

例如,考虑以下函数:

// 1. Use expression as and when needed, no new variables
void MyFunction1(int a, int b)
{
    SubFunction1(a + b);
    SubFunction2(a + b);
    SubFunction3(a + b);
}

// 2. Re-use existing function parameter variable to compute
// result once, and use result multiple times.
// (I've seen this approach most in old-school C code)
void MyFunction2(int a, int b)
{
    a += b;
    
    SubFunction1(a);
    SubFunction2(a);
    SubFunction3(a);
}

// 3. Use a new variable to compute result once,
// and use result multiple times.
void MyFunction3(int a, int b)
{
    int sum = a + b;
    
    SubFunction1(sum);
    SubFunction2(sum);
    SubFunction3(sum);
}

// 4. Use a new const variable to compute result once,
// and use result multiple times.
void MyFunction4(int a, int b)
{
    const int sum = a + b;
    
    SubFunction1(sum);
    SubFunction2(sum);
    SubFunction3(sum);
}

我的直觉是:

我的假设是否正确?是否还有更多因素需要考虑?

编辑:针对评论的一些澄清:

优秀的现代编译器通常不会“关心”您用来存储值的名称。他们对这些值进行生命周期分析并基于此生成代码。例如,给定:

int x = complicated expression 0;
... code using x
x = complicated expression 1;
... code using x

编译器会看到在第一段代码中使用了complicated expression 0,在第二段代码中使用了complicated expression 1,名称x是无关紧要的。结果将与代码使用不同的名称相同:

int x0 = complicated expression 0;
... code using x0
int x1 = complicated expression 1;
... code using x1

所以为了不同的目的重用一个变量是没有意义的;它不会帮助编译器节省内存或以其他方式优化。

即使代码在循环中,例如:

int x;
while (some condition)
{
    x = complicated expression;
    ... code using x
}

编译器会看到complicated expression诞生于循环体的开头,结束于循环体的结尾。

这意味着您不必担心编译器将如何处理代码。相反,您的决定应该主要以更清晰的编写和更有可能避免错误的内容为指导:

  • 避免为多个目的重复使用一个变量。例如,如果有人稍后更新您的函数以添加新功能,他们可能会错过您已使用 a += b; 更改函数参数并在代码中稍后使用 a 的事实,就好像它仍然包含原始参数.
  • 自由创建新变量来保存重复的表达式。 int sum = a + b; 可以;它表达了意图,并在多个地方使用相同的表达方式时使读者更清楚。
  • 限制变量(和一般标识符)的范围。仅在需要它们的最内层范围内声明它们,例如在循环内部而不是外部。避免在不再适用的地方意外使用变量。