6

使用 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 尽可能。

4

2 回答 2

8

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

于 2012-04-09T01:19:18.597 回答
2

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

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

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

— ...

于 2012-04-09T07:34:34.780 回答