#032 – Why function arguments may not evaluate left-to-right

Consider the following,


#include <iostream>

int getValue() {
    std::cout << "Enter a number\\n";
    int x {};
    std::cin >> x;
    return x;
}

void cal(int x, int y, int z) { std::cout << x + (y * z); }

int main()
{

    cal(getValue(), getValue(), getValue());
}

// Terminal
Enter a number
2
Enter a number
3
Enter a number
1
7 // NOT 5

The result isn’t 5 ?? cal should print 2 + (3 * 1) = 5.

What’s going on?

You’re assuming the function arguments gets evaluated left-to-right, cal(2, 3, 1). However, the first argument doesn’t necessarily have to be in the first argument position. Same for the 2nd and 3rd argument.

Thus,

calculate(getValue(), getValue(), getValue() );

does not guarantee that the leftmost getValue() call runs first.

A compiler may evaluate the arguments in a different order. In fact:

The Clang compiler evaluates arguments in left-to-right order. The GCC compiler evaluates arguments in right-to-left order.

The distinction

The arguments do not change positions. They get initialized according to their location in the parameter list. Although, the order in which they are evaluated is left to the compiler.

The solution

The solution is to be explicit about what gets passed in. In this program, doesn’t matter in which order the function arguments get evaluated in.

#include <iostream>

int getValue()
{
    std::cout << "Enter an integer: ";
    int x{};
    std::cin >> x;
    return x;
}

void printCalculation(int x, int y, int z) { std::cout << x + (y * z); }

int main()
{
    int a{ getValue() }; // will execute first
    int b{ getValue() }; // will execute second
    int c{ getValue() }; // will execute third

    printCalculation(a, b, c); // No ambiguity about order of operations
}

Leave a Reply

Your email address will not be published. Required fields are marked *