c++ Order of parameter evaluation

Order of parameter evaluation in C++ | Peter Bloomfield

The low-level details of how data gets passed into a function are often overlooked by programmers. We obviously care about passing parameters by value vs. reference and by copy vs. move, but it’s easy to ignore anything deeper than that.

With C++ in particular, this can cause an unexpected problem regarding the order in which things actually happen. In this post, we’ll look at what can go wrong, and how to deal with it.

Simple example

Let’s say we’ve got a function which needs to be given two numbers. However, we don’t have those numbers stored in variables yet. Rather, we need to call two other functions to get those values. For example:

#include <iostream>

void doStuff(int a, int b) { }

int getA()
{
    std::cout << "A";
    return 1;
}

int getB()
{
    std::cout << "B";
    return 2;
}

void main()
{
    doStuff( getA(), getB() );
}

 

What is the execution path in main()?

Obviously getA() and getB() must both be called before doStuff() can be called. That much absolutely must be true. However, it’s also tempting to make the assumption that getA() will be called before getB().

In reality, this may not be the case. If you run the program, the output is likely to be “BA”, indicating that the parameters were evaluated in reverse order. Note that it depends on your compiler though. In theory, you may see different results depending on which one you use.

Why does this happen?

The C++ standard does not specify the order in which function parameters need to be evaluated. The calling convention dictates the order in which the parameters are passed, but there’s no requirement to evaluate them the same way.

In my experience though, it’s common to see the parameters evaluated in reverse order (right-to-left). Hypothetically, a compiler may change the order if there is (for example) some opportunity for performance gain, but it seems unlikely.

The C++17 standard defines the order of evaluation under certain circumstances. However, it will not affect the example above.

How to fix it?

If you absolutely must depend on a particular order of evaluation, then explicitly do the evaluation before calling the function. Using the above example, you would call getA() and store the result in a local variable, then call setB() and store the result in another local variable. After both of those, you would call doStuff(), passing it those local variables.

 

Stricter Expression Evaluation Order in C++17

 

posted @ 2025-06-13 20:05  ChuckLu  阅读(15)  评论(0)    收藏  举报