My FeedDiscussionsHashnode Enterprise
New
Sign in
Log inSign up
Learn more about Hashnode Headless CMSHashnode Headless CMS
Collaborate seamlessly with Hashnode Headless CMS for Enterprise.
Upgrade ✨Learn more
Argument Evaluation Order in C++

Argument Evaluation Order in C++

Aditya Agarwal's photo
Aditya Agarwal
·May 17, 2020

I am here discussing "Don’t depend on the order of evaluation of function arguments". Now I think you may worry, what I am talking about because many Developers assumed that the order of the evaluation of function arguments is left to right. Wrong! You have no guarantees!

Reason Because that order is unspecified.

Note C++17 tightens up the rules for the order of evaluation, but the order of evaluation of function arguments is still unspecified.

Now take simple example:

//test.cpp

#include <iostream>

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

int main() {
    int i = 0;
    foo(i++, i++); // (1, 0) | (0, 1) | (0, 0)

    return 0;
}

If you understand what I am saying why this comment then you actually on the way. If not then get a move to the explanation.

Here is my proof. The output from gcc and clang differs:

  • gcc

g++ -std=c++2a -O3 -Wall test.cpp -o test && ./test

test.cpp: In functionint main()’:
test.cpp:9:15: warning: operation onimay be undefined [-Wsequence-point]
    9 |     foo(i++, i++); // (1, 0) | (0, 1) | (0, 0)
      |              ~^~
test.cpp:9:15: warning: operation on ‘i’ may be undefined [-Wsequence-point]
a: 1 b: 0
  • clang

clang++ -std=c++2a -O3 -Wall test.cpp -o test && ./test

test.cpp:9:10: warning: multiple unsequenced modifications to 'i' [-Wunsequenced]
    foo(i++, i++); // (1, 0) | (0, 1) | (0, 0)
         ^    ~~
1 warning generated.
a: 0 b: 1

The call will most likely be foo(0, 1) or foo(1, 0), but you don’t know which. Technically, the behavior is undefined. In C++17, this code does not have undefined behavior, but it is still not specified which argument is evaluated first.

I compile in C++20 or give the best possible error in compilation with optimization with a compiler flag.

If you want to learn more about this then follow these links: