编译器会优化和重用变量吗?

时间:2016-10-06 20:15:36

标签: c++ gcc optimization clang

例如,如果我有以下代码:

int main(){
  myClass a(...);
  a.doSomething();
  if(...){
    myClass c(...);
    c.doSomething();
  }
}

像gcc或clang这样的通常编译器会通过找出" a"来优化这些变量的使用。在它的生命周期中不再使用,而不是为" c"重新分配空间,只是使用空间?如果这不适用于课堂,那么这是否适用于"传统"类型为double或size_t?

我试图最小化频繁调用函数的分配成本。但是在函数内部的某个地方,我觉得一些旧的变量已经没用了,但新变量不应该被称为该名称。编译器会直接为我重用变量,还是应该像

那样做
myClass a(...);
something(a);
if(...){
  #define c a
  c=myClass(...);
  something c;
  #undef c
}

2 个答案:

答案 0 :(得分:5)

通常,不允许编译器在其作用域结束时重用a,这是函数末尾的右括号}。当析构函数执行一些特殊代码 * 时,此功能(在可预测的时间销毁对象)可以在C ++中生成保护。

  

我试图最小化频繁调用函数的分配成本。

由于分配自动变量的成本几乎为零,因此大部分成本是在调用构造函数时。这不是你可以优化的东西。

* 如果你的对象有简单的析构函数,编译器可以重用内存。这可以节省你的记忆,而不是时间。

答案 1 :(得分:0)

这些变量在堆栈上分配。即使编译器不重用该空间,也不会导致任何额外的CPU指令,只会导致RAM。堆栈上的分配只是将已分配的字节数添加到堆栈指针。通常通过添加函数中存在的所有变量的大小来完成一条指令。在任何情况下,编译器都足够智能,可以重用分配变量的CPU寄存器。

注意,如果你的类有析构函数,那么它们必须持续到块的结尾。因此,在这种情况下,变量a的内存将不会被重用,因为在函数结束时需要它。但是编译器仍然可以重用用于它的寄存器。