Harald van =?UTF-8?b?RMSzaw==?= wrote:
[ printf("%d %d\n", ++n, power(2,n)); ]
The call to printf starts before any of its arguments are evaluated.
What matters is when the call to power starts, as that is the only
possible sequence point between the evaluation of ++n and n. I don't
believe it starts before its arguments are evaluated. The requirement of
a sequence point "before the actual call" is what allows
int a;
int f(int ignored) { return a; }
int g(void) { return f(++a); }
where g() must run as
- evaluate ++a
* call f
- evaluate a
- return
Are you saying this too is instead run as
* call f
- evaluate ++a
- evaluate a
- return
? If so, where is the sequence point between evaluation of ++a and
evaluation of a? If there is none, the behaviour would be undefined, and
I'm fairly confident the behaviour is well-defined here.
The relevant text in the standard is
"The order of evaluation of the function designator, the actual
arguments, and subexpressions within the actual arguments is unspecified,
but there is a sequence point before the actual call."
I've always read "the actual call" as the point where control transfers
to the called function (typically, when the generated BSR instruction or
equivalent is reached).
power returns before printf does.
There are only two different outputs that the above quoted C statement
can produce.
The choices need not be documented.
That's unspecified behavior.
If you're correct about when the call starts, then I agree the behaviour
is unspecified. Otherwise, if there is no sequence point between the
evaluation of ++n and n, there are no restrictions on the behaviour, as
it is explicitly undefined.