【问题标题】:compiler optimization of return value in VS 2010VS 2010中返回值的编译器优化
【发布时间】:2012-04-21 12:17:37
【问题描述】:

使用 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 并且当设置了某个编译标志时,我希望它将输入附加到副本并返回它,当未设置编译标志时,我希望它尽可能接近否-op 尽可能。

【问题讨论】:

    标签: c++ optimization inline compiler-optimization return-value-optimization


    【解决方案1】:

    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

    【讨论】:

      【解决方案2】:

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

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

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

      ——……

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-06-07
        • 2010-09-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-09
        • 1970-01-01
        相关资源
        最近更新 更多