Unspecified behavior example

Just need a sanity check. The following would be unspecified, but not undefined, correct?
I am 99% sure it's just unspecified.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
int x = 0;

int f() {
    return x++;
}
int g() {
    return x++;
}
void h(int y, int z) { std::cout << y << z << std::endl; }

int main()
{
    h( f(), g() ); // order of evaluation here is unspecified, or completely undefined?
}

In other words, is the set of possible outputs of this program:
{ "01", "10"} or
{ "01", "10", "banana", pizza delivery, ... }
Last edited on
It is unspecified.
http://en.cppreference.com/w/cpp/language/eval_order

I wish my undefined behavior ordered pizza for me.... :(

Edit:
I linked the wrong reference page (the one for C.) It's now correct.
Last edited on
The program definitely works so it's not undefined. I compiled your code using the g++ compiler and it outputs "10". You're definitely a sane person as far as I know! It is just unspecified, for the compiler decides which parameters to evaluate first.
haha thanks
The program definitely works so it's not undefined

That's a dangerous assumption.
Last edited on
Speaking of which, I discovered that when one of my programs went out of bounds, it would always, without fail, cause someone to ring my doorbell around 30 minutes later, with a half-off pizza to deliver. But ever since that Meltdown fix, my program just crashes instead. Microsoft broke my workflow >:(
Last edited on
You are correct.
What is “unspecified” is the evaluation order of function arguments (this includes in mathematical operations): the value of arguments may be computed in any order, meaning that the functions f() and g() may be invoked in any order.

    x = f() + g() * h();        // the functions may be called in any order!

If it makes a difference whether one function is called before the other, do it first:

    auto g_result = g();
    auto h_result = h();
    auto f_result = f();
    x = f_result + g_result * h_result;

Hope this helps.
The evaluations of the two sub-expressions f() and g() are indeterminately sequenced - they can't be interleaved.

(I'm pointing this out in case it was the i++ causing the confusion. Presumably if the evaluations were unsequenced, the program's behavior would be undefined rather than merely unspecified.)
Last edited on
One thing to keep clear in your head is the difference between precedence/associativity and order of evaluation. Precedence and associativity define the order of the operations. Order of evaluation defines the order in which the operands are evaluated.

Put another way, precedence tells you where the implicit parentheses go: is a - b - c evaluated as (a - b) - c or a - (b - c)? The language usually defines this.

Order of evaluation defines the order in which a, b, and c are evaluated (and when the intermediate result is evaluated too). This is almost always NOT specified.
Thanks for the replies, everyone. Separating f() and g() calls into different lines seems to be the best way to extinguish the theoretical problem.
Topic archived. No new replies allowed.