On 03/23/17 01:38, Gavin Lambert via Boost wrote:
On 23/03/2017 03:28, Olaf van der Spek via Boost wrote:
void f2(const string&); string f1();
f1(f2());
Isn't this a very common pattern?
Yes (although you have it reversed), but that's not what we were talking about. We were talking about this:
void f1(const string_ref&); string f2();
f1(f2());
Or this:
void f1(const string_ref&); string_ref f2(const string_ref&); string f3();
f1(f2(f3()));
They both *should* be safe because the temporary string should not be destroyed until after f1 is called. But some old/embedded compilers would sometimes get this wrong when optimising.
IMHO, compiler bugs should not be the reason for interface design choices. And BTW, I know Sun Pro compiler (Oracle Studio nowdays) had a mode with the opposite behavior - it would not destroy temporaries until the end of the scope.
You can also get into trouble even on modern compilers if binding is involved in certain patterns, since then the full-expression might end before the call actually happens.
I did make an error in my initial response; I've just been burned by buggy implementations in the past and it makes me nervous, so I jumped the gun. I apologise for any confusion.
Whatever we decide to do about this issue, I think we should make the choice before 1.64 is released. I think, this is a new change for 1.64, and it's not too late to roll it back if we choose so (IMHO, we should).