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.