条件堆栈变量

lcs*_*lcs 15 c++

给定以下函数,是否会在堆栈中声明每个局部变量?

std::string reallyCoolFunction(unsigned int a)
{
   if( a < 20 ) 
   {
     std::string result1 = "This function is really cool";
     return result1;
   }

   if( a >=20 && a <= 40 )
   {
     std::string result2 = "This function is kind of cool";
     return result2;
   }

   if( a > 40 )
   {
     std::string result3 = "This function is moderately cool";
     return result3;
   }

 std::string result4 = "This function really isn't that cool"; 
 return result4; // remove warning

}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,std::string实际上只需要一个,在堆栈上分配所有4个,或者只分配1个吗?

das*_*ght 14

决定取决于编译器:由于自动变量在下一个范围进入范围之前超出范围,编译器可以重新使用它们的内存.请记住,"堆栈"变量实际上是根据C++规范具有自动存储持续时间的变量,因此它们可能根本不在堆栈中.


izo*_*ica 10

在大多数编译器中,只分配一个字符串.请记住,虽然std::string使用动态内存,但其大部分内容仍将在堆上分配.

  • 字符串*可以*使用动态内存,但不一定.例如,参见MSVC标准库中的小字符串优化. (5认同)

Mat*_* M. 6

最可能是0或者1(在发布中),当然是4(在Debug中).

这称为RVO:返回值优化.

实际上允许编译器完全删除副本并std::string直接在调用者提供的插槽中构建.这是ABI特定的,因为所有优化仅适用于满足多个标准的情况; 在你的情况下,它很可能适用.

如果要检查,可以尝试在其转换/优化管道的各个阶段仔细阅读编译器的输出; 它可能很难,但取决于你的工具链.