Why does the execution order of function call arguments not follow the specified order?

137 views Asked by At

I am reading the book of CPP-Concurrency-In-Action-2ed-2019. In chapter 5.3.2, the author gives a simple example:

#include <iostream>

void foo(int a, int b)
{
    std::cout << a << ", " << b << std::endl;
}

int get_num()
{
    static int i = 0;
    return ++i;
}

int main()
{
    foo(get_num(), get_num());
}

It says the two times of calling get_num() are in random sequence. And it could output 1, 2 or 2, 1.

But is it the same with below, which is definitely output in a fixed sequence.

int main()
{
    auto a = get_num();
    auto b = get_num();
    foo(a, b);
}

So why does the former output randomly?

3

There are 3 answers

0
chrysante On

It boils down to: "These are the rules"

The C++ standard committee decided that they don't want to specify an order. This leaves it up to the compiler to decide which argument to evaluate first. The compiler may decide that the code would be more efficient if b is evaluated before a or the other way around. If the committee would have decided that the arguments need to be evaluated in order, compilers might have to generate less efficient code in certain situations.

0
JeJo On

The behavior of the first code snippet is due to the reason that the order of evaluation of the function arguments is unspecified. This means the compiler can evaluate the function arguments

foo(get_num(), get_num());  

in any order, depending on how they are implemented get the best optimization. Read more related posts:

0
tbxfreeware On

In addition to the technical issues described above, there are also political considerations. And, yes, the standards committee is a political animal.

By the time the standards committee was facing this issue, there already were significant compilers in widespread use. Some of them did it one way, and some, the other. If the committee had picked a winner, it would have placed very real burdens on the losers. Not only would they have to rework their compilers, they would also face the issue of what to do about a large installed base of programs that had been created with their compilers. Some of those products would need to be recompiled and reshipped to customers.

So the best thing, politically, was to declare everyone to be a winner! Nobody had to rework their compiler, and nobody had to contact the buyers of its compiler to explain that products created with the compiler might need to be modified, recompiled and reshipped.