Unspecified behavior example

Jan 9, 2018 at 10:45pm
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 Jan 9, 2018 at 11:01pm
Jan 9, 2018 at 11:44pm
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 Jan 10, 2018 at 5:05am
Jan 9, 2018 at 11:47pm
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.
Jan 9, 2018 at 11:48pm
haha thanks
Jan 9, 2018 at 11:48pm
The program definitely works so it's not undefined

That's a dangerous assumption.
Last edited on Jan 10, 2018 at 5:23am
Jan 10, 2018 at 12:00am
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 Jan 10, 2018 at 12:01am
Jan 10, 2018 at 4:14am
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.
Jan 10, 2018 at 5:16am
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 Jan 10, 2018 at 5:19am
Jan 10, 2018 at 10:09pm
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.
Jan 10, 2018 at 10:49pm
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.