首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++返回值优化,多个未命名返回

C++返回值优化,多个未命名返回
EN

Stack Overflow用户
提问于 2016-07-11 15:56:31
回答 1查看 3.1K关注 0票数 11

让我们考虑这两个函数:

代码语言:javascript
复制
// 1. Multiple returns of the same named object
string f() {
    string s;
    if (something())
        return s.assign(get_value1());
    else
        return s.assign(get_value2());
}

代码语言:javascript
复制
// 2. Multiple returns, all of unnamed objects
string g() {
    if (something())
        return get_value1();
    else
        return get_value2();
}

每个函数在RVO方面的实际行为当然是依赖于编译器的。然而,我是否正确地认为,RVO对两者都是常见的呢?

附注:(见答案)函数#1的目的是:

代码语言:javascript
复制
string f() {
    string s;
    if (something())
        return s;
    s.assign(get_value());
    return s;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-07-11 20:39:45

对于#1,NRVO保证不会发生,也就是说,您保证从s获得一个副本到函数的返回值。在这种情况下,你最好还是

代码语言:javascript
复制
return std::move(s.assign(get_value1()));

或者,如果可能的话,重写该函数使其对NRVO友好:

代码语言:javascript
复制
string f() {
    string s;
    if (something())
        s.assign(get_value1());
    else
        s.assign(get_value2());
    return s;
}

在编译器考虑NRVO之前,必须满足几个标准要求。这里不满意的是,return语句中的表达式必须是变量的名称。s.assign(...)不是一个名称,它是一个更复杂的表达式;为了考虑NRVO,您需要有类似于return s;的东西。

对于#2,假设get_value函数返回string (或const string),那么在任何现代编译器上都很可能有RVO,而且,如果所有这些都符合C++17的批准,那么RVO将在任何符合的编译器中以C++17模式得到保证(对于NRVO仍然没有任何保证)。

您可以在cppreference.com上找到关于(N)RVO (在标准中称为复制省略)的非常好和全面的信息。

我决定检查当前的编译器状态,所以我对GCC 6.1.0、Clang 3.8.0和MSVC 2015更新3进行了一些测试。

对于#2,您可以从所有三个编译器获得RVO ( return语句中的prvalue很容易分析)。

您还可以从所有三个编译器获得NRVO,其结构类似于上面的“NRVO友好”(对于MSVC,您需要启用优化)。

但是,对于这样的函数

代码语言:javascript
复制
string f() {
    string s;
    if (something())
        return s;
    s.assign(get_value());
    return s;
}

GCC和Clang做NRVO,但MSVC没有;但是它会生成从s到返回值的移动,这是标准一致性。

另一个例子是:

代码语言:javascript
复制
string f() {
    string s;
    if (something())
        return get_value1();
    if (something_else())
        return get_value2();
    s.assign(get_value3());
    return s;
}

所有三个编译器都对前两个return执行RVO操作,而对于第三个编译器则从s迁移到RVO。

票数 17
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38311297

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档