I just find out that this little piece of C++ code doesn't give me the same result with clang++ and with g++:
#include <iostream>
#include <string>
using namespace std;
const string& createString(char c) {
static string s;
s="";
for(int i=0; i<10; ++i) {
s+=c;
}
return s;
}
int main() {
cout << createString('a') << ' ' << createString('z') << endl;
return 0;
}
With clang++ it writes:
aaaaaaaaaa zzzzzzzzzz
like I want it to be, but with g++ it writes:
aaaaaaaaaa aaaaaaaaaa
Why is it so? Is the g++ implementation standard compliant? And what should I do if I want a function to return a temporary "big" type by reference like here to avoid useless copy?
Yes, both implementations are compliant. The order of evaluation of function arguments is not specified.
Therefore, createString('a')
and createString('z')
can be evaluated in any order. Furthermore, createString('z')
can be evaluated before or after the result of createString('a')
is written out.
Since the function is stateful, and returns the state by reference, both outputs are permissible, as is zzzzzzzzzz zzzzzzzzzz
.
Finally, it is worth noting that having static
state would be a major headache in a multithreaded environment.
And what should I do if I want a function to return a temporary "big" type by reference like here to avoid useless copy ?
It won't be. RVO and NRVO can trivially take care of this. In addition, move semantics. In short, there's nothing problematic about returning a std::string
by value at all.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With