Moos Hueting Moos Hueting - 1 year ago 82
C++ Question

Is the compiler allowed to interlace the evaluation of subexpressions within different function arguments?

I am wondering about the following situation:

void f(int a, int b) { }

int a(int x) { std::cout << "func a" << std::endl; return 1; }
int b(int x) { std::cout << "func b" << std::endl; return 2; }

int x() { std::cout << "func x" << std::endl; return 3; }
int y() { std::cout << "func y" << std::endl; return 4; }

f(a(x()), b(y()));

After reading I am still having difficulty to understand whether the following evaluation order is possible:


or that the standard guarantees that
will be evaluated as units, so to speak.

In other words, is there any possibility this will print

func x
func y
func a
func b

Running this test on GCC 5.4.0 gives the to my mind more logical

func y
func b
func x
func a

but this of course does not tell me anything about what the standard requires. It would be nice to get a reference to the standard.

Answer Source

In C++14 and earlier, x -> y -> a -> b is possible. The sequencing relations here are:

  • Call to x is sequenced before call to a.
  • Call to y is sequenced before call to b.
  • Call to a is sequenced before call to f.
  • Call to b is sequenced before call to f.

There are no other restrictions on the order. If you want to enforce some particular ordering then you'll have to break this call up into multiple full-expressions.

As noted in comments, the cppreference page lists some more sequencing rules marked as "since C++17". However, p0145r3 chapter 8 says that this sequencing proposal was not pursued , as of a Spring 2016 meeting.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download