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

Reply via email to