Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 编译器会优化和重用变量吗_C++_Gcc_Optimization_Clang - Fatal编程技术网

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

C++ 编译器会优化和重用变量吗,c++,gcc,optimization,clang,C++,Gcc,Optimization,Clang,例如,如果我有以下代码: int main(){ myClass a(...); a.doSomething(); if(...){ myClass c(...); c.doSomething(); } } 像gcc或clang这样的普通编译器是否会通过发现a在其生命周期中将不再使用而优化这些变量的使用,而不是为c重新分配空间,只使用a的空间?如果这在课堂上不起作用,那么在传统的双码或大号的字体上会起作用吗 我试图最小化频繁调用函数的分配成本。但是在函数内部的某

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

int main(){
  myClass a(...);
  a.doSomething();
  if(...){
    myClass c(...);
    c.doSomething();
  }
}
像gcc或clang这样的普通编译器是否会通过发现a在其生命周期中将不再使用而优化这些变量的使用,而不是为c重新分配空间,只使用a的空间?如果这在课堂上不起作用,那么在传统的双码或大号的字体上会起作用吗

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

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

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


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

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


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

一般来说,编译器在其作用域结束之前不允许重用a,即函数末尾的右括号}。在可预测的时间内破坏对象的特性使得在C++中,当析构函数执行一些特殊代码*/< 我试图最小化频繁调用函数的分配成本

由于分配自动变量几乎不需要任何成本,因此大部分成本都是调用构造函数。这不是你可以优化掉的东西


*如果对象具有平凡的析构函数,编译器可以重用内存。这将节省内存,而不是时间。

通常,编译器在其作用域结束之前不允许重用,即函数结尾处的右括号}。在可预测的时间内破坏对象的特性使得在C++中,当析构函数执行一些特殊代码*/< 我试图最小化频繁调用函数的分配成本

由于分配自动变量几乎不需要任何成本,因此大部分成本都是调用构造函数。这不是你可以优化掉的东西


*如果对象具有平凡的析构函数,编译器可以重用内存。这将节省内存,而不是时间。

您的探查器是否会告诉您这是应用程序中的一个热点,生成的程序集会说什么?关于:{myClass a;a.doSomething;}{if…{myClass c;c.doSomething;}}}GCC即使在函数体中存在短作用域,也不能很好地重用堆栈空间。但是我相信它已经更好了。对于C分配的C++类类,答案很可能不同于C标量。由于您显然关注的是类实例,所以应该从标记列表中删除[c]。@gmannick这是一个在主函数中调用大约1000000次的函数,存储开销很大,我不能在主函数中内联,因为我需要递归。尚未尝试探查器或生成程序集。探查器是否告诉您这是应用程序中的一个热点,生成的程序集说明了什么?如何:{myClass a;a.doSomething;}{if…{myClass c;c.doSomething;}}}}}GCC即使在函数体中存在短作用域,也无法很好地重用堆栈空间。但是我相信它已经更好了。对于C分配的C++类类,答案很可能不同于C标量。由于您显然关注的是类实例,所以应该从标记列表中删除[c]。@gmannick这是一个在主函数中调用大约1000000次的函数,存储开销很大,我不能在主函数中内联,因为我需要递归。尚未尝试探查器或生成程序集。它必须在堆栈上吗?这些只是自动变量。使用堆栈依赖于实现。那么,它们可能会被优化掉并放置在
登记册。在这种情况下,没有分配成本,寄存器重用是编译器必须做得足够好的事情。它必须在堆栈上吗?这些只是自动变量。堆栈的使用依赖于实现。嗯,它们可能会被优化掉并放在寄存器上。在这种情况下,没有分配成本,编译器必须充分做好寄存器重用。每个对象都有一个析构函数。每个对象都有一个析构函数。