简体   繁体   中英

Does the compiler avoid a copy when returning a string that is taken as const reference?

I wander if the compiler will optimize away the copy in the following situation. I have a class whose only resource member is a string that may be a few KB large. I want to have a public member of this class to access that string and I am not sure if I should have this member returning a reference or simply by value. Suppose that I choose to return by value like so

class A { 
  public: 
    A();
    ~A();
    std::string getString() { return str; } 
  private:
    std::string str;
} 

int main() { 
  A *a = new A;
  const std::string& str = a->getString();
  std::cout << str;
}

Will the compiler optimize and avoid the copy if I take the result as a const std::string& as in main ?

It's remotely possible, but is highly unlikely that the compiler will optimize away a copy in this use case.

Observe that if the copy gets optimized away, the caller's temporary essentially gets bound as a const reference to the object's class member. And const means that the referenced value cannot be changed.

With only the code shown in this question, it's possible that the compiler can prove to itself that nothing can possibly change the contents of the class member while the const reference remains in scope, and so it is safe to make this optimization.

But things get muddy very quickly, in a more generalized case. If there are other class methods that can potentially change the contents of the referenced class member, if there are any calls during the const reference's lifetime to functions or methods whose definition is not visible; the most likely result is that the compiler will have no way of knowing if it's possible for the referenced class member to be modified during the const reference's entire execution scope, and thus it will be forced to make a copy of the string, in order to guarantee its const -ness.

A compiler is free to make only those optimization that result in no visible, observed changes in a well-formed program. If the compiler cannot prove that the optimization results in no visible, observable changes then the optimization will not be performed.

PS Note that "modification" also includes destruction. The proposed optimization binds the const reference to an object in dynamic scope. If there are any intervening calls to delete -- explicitly or implicitly as part of calls to various library container methods -- the compiler will also have to prove to itself that the delete d object cannot be the object with the bound const reference.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM