On Thu, Jan 29, 2015 at 10:38 PM, Conrad S <conradsand.a...@gmail.com> wrote: > > Which compiler is correct here - gcc or clang?
Both compilers are correct. > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64870 > > Consider the following code: > > #include <iostream> > > struct blah { > inline double setval(unsigned int& x) const > { > x = 123; > return 456.0; > } > }; > > > int > main(int argc, char** argv) { > blah blah_instance; > > unsigned int val = 9999; > > std::cout << blah_instance.setval(val) << " val: " << val << std::endl; > std::cout << blah_instance.setval(val) << " val: " << val << std::endl; > > return 0; > } > > when compiled with gcc 4.9.2, the above program produces: > 456 val: 9999 <-- unexpected > 456 val: 123 > > when compiled with clang 3.5: > 456 val: 123 > 456 val: 123 > > Clang has the least surprising result. Is gcc relying on a loophole in > C++ legalese to muck up the order of evaluation? It's hardly just a loophole: C++ doesn't specify the order of evaluation, so the code is wrong (i.e., non-portable, as you've found). Arguably this is a design problem with IOStreams, given how tempting it can be to write code that assumes left-to-right evaluation, but it's not a compiler bug. -- James