VS 2010 中返回值的编译器优化



使用 VS 2010 和完全优化/Ox 查看以下两个函数调用:

static string test1(const string& input)
{
    return input;
}
static void test2(const string& input, string& output)
{
    output = input;
}

如果我使用后一个 test2,那么函数总是被优化出来,代码内联。 但是,除非我关闭异常,否则 test1 不会内联。 有谁知道这是为什么?

此外,如果编译器使用返回值优化,我希望编译器能够在 test1 中像 test2 一样高效地完成工作,但它似乎没有这样做。这也让我感到困惑。

我想使用第一个函数签名的原因是我有两个可编译的函数版本。 我希望调用代码始终调用test1,当设置某个编译标志时,我希望它将输入附加到副本并返回它,当未设置编译标志时,我希望它尽可能接近无操作。

Visual Studio 不能内联函数返回具有非平凡析构函数的对象:

在某些情况下,由于机械原因,编译器不会内联特定函数。例如,编译器不会内联:
  • 一个函数,如果它会导致混合 SEH 和 C++ EH。
  • 某些函数在 -GX/EHs/EHa 打开时复制按值传递的构造对象。当
  • -GX/EHs/EHa 打开时按值返回不可展开对象的函数。
  • 在没有 -Og/Ox/O1/O2 的情况下编译时使用内联程序集的函数。
  • 具有变量参数列表的函数。
  • 具有 try(C++异常处理)语句的函数。

http://msdn.microsoft.com/en-us/library/a98sb923.aspx

当返回值是函数的参数时,该标准明确禁止编译器使用返回值优化 (12.8/31):

在以下情况下允许这种复制/移动操作省略(称为复制省略),这些情况(可以组合以消除多个副本):

— 在具有类返回类型的函数的 return 语句中,当表达式是与函数返回类型具有相同 CV-unqualified 类型的非易失性自动对象(函数或 catch 子句参数除外)的名称时,可以通过将自动对象直接构造到函数的返回值中来省略复制/移动操作

— ...

最新更新