Reputation: 33
Take the following example:
int g_X;
int func() {
return ++g_X; // using g_X++ is not an option
}
int main() {
g_X = 0;
int a = g_X + func();
g_X = 0;
int b = func() + g_X;
g_X = 0; int temp = g_X;
int c = temp + func();
return 0;
}
a and b are both 2, c has the expected value 1 (tested with Visual Studio 2010 to 2015). I read that sums are not associated with a sequence point (e.g. https://en.wikipedia.org/wiki/Sequence_point) and therefore the order is not fixed. Yet I thought that the value of g_X gets captured before the function call. Am I really in undefined behavior territory or is there some way not having to use the temp var?
Upvotes: 3
Views: 113
Reputation: 55554
At first sight this looks like an undefined behavior because, quoting §1.9/15:
If a side effect on a scalar object is unsequenced relative to either another side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined.
and your example seemingly satisfies these conditions:
func
increments g_X
).g_X
).On the other hand, as pointed out in the Brian's answer, function call does introduce sequencing, although indeterminate. According to this argument this is not an undefined behavior, but merely unspecified.
Upvotes: 2
Reputation: 119144
Every evaluation in the calling function (including other function calls) that is not otherwise specifically sequenced before or after the execution of the body of the called function is indeterminately sequenced with respect to the execution of the called function.
([intro.execution]/15)
Therefore, in an expression of the form g_X + func()
or func() + g_X
, it's true that the +
operator doesn't introduce any sequencing constraint, but nevertheless the access to g_X
within main
either happens before or after the body of func()
, you just can't predict which. This implies that the behaviour is defined, but whether a
is 1 or 2 is unpredictable. Likewise, whether b
is 1 or 2 is unpredictable.
Upvotes: 2