int f() {
static int i=0;
return ++i;
}
int g() {
return f() + f();
}
Does g()
return 3
or is the result undefined
?
Chapter and verse:
6.5.2.2 Function calls
...
10 There is a sequence point after the evaluations of the function designator and the actual arguments but before the actual call. 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.94)
94) In other words, function executions do not ‘‘interleave’’ with each other
Upshot is that there is a sequence point between each ++i
by virtue of it being part of a function call. Thus, this behavior is well-defined.
Whether it actually does what you intend is another matter. Note that at some point you risk signed overflow, which is undefined. And as others have pointed out, f() - f()
may not give the result you would expect (left to right evaluation is not guaranteed in that case).
The evaluations of the two operands of the + operator are unsequenced1.
There is a sequence point just before the actual function call2. This sequence point is enough to separate the modifications of static variable i, making the entire expression indeterminately sequenced, and the order of the function calls unspecified3.
Thus the behavior remains defined, and the first call to function g will always yield 3, since the unspecified order of the function calls doesn't influence the result.
A program containing unspecified behavior is defined4.
(All quotes are from: ISO/IEC 9899:201x)
1 (6.5 Expressions 3)
Except as specified
later, side effects and value computations of subexpressions are unsequenced.
2 (6.5.2.2 Function calls 10)
There is a sequence point after the evaluations of the function designator and the actual
arguments but before the actual call.
3 (5.1.2.3 Program execution 3)
Evaluations A and B are indeterminately sequenced when A is sequenced
either before or after B, but it is unspecified which.
4 (4. Conformance 3)
A program that is correct in all other aspects, operating on correct data, containing
unspecified behavior shall be a correct program and act in accordance with 5.1.2.3.
There is no reason for this to be undefined, because +
operation is commutative, and because there are sequence points for the two ++
operations to be sequenced.
C standard has sequence points after a full expression, and also before a function is entered in a function call. Therefore, the results of ++
will be fully sequenced. Moreover, since +
is commutative, the order of calls to f()
does not change the result.
Note that the same logic would not apply to
return f() - f();
because -
is not commutative. The result of the expression above is unspecified, i.e. a standard-compliant compiler could reasonably produce a 1
or a -1
, depending on the order in which the compiler calls the two f()
functions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With