Barry said:
(e-mail address removed) wrote:
#include <stdio.h>
int* f(int x)
{
static int d[4];
static int done[4];
static int twice;
done[x]=1;
if(x==2 && done[0] && done[1])
twice=1;
if(x==3 && twice)
return &d[1];
else
return &d[x];
}
int main(void)
{
printf("%d\n", ( (*f(0))++, (*f(1))++ ) + ( (*f(2))++, (*f(3))++ )
);
return 0;
}
Undefined behavior.
Since there are sequence points before each function call to f, why do
you think this is any worse than implementation defined behavior.
The object d[1] can be updated more than once after all
the calls to f have completed.
I don't understand your reasoning here!
In x=(x=5,11);
I am saying that both updates of the x can start at the beginning of
the statement. The x=5 has to complete by the comma and the x=11 has to
complete at the semicolon. Hence there is a period where two updates
can be affecting the same variable at the same time.
You seem to think that the comma operator puts a limit on when the x=11
can _start_.
(fair enough - I actually think this was the intent of the standard
authors otherwise things like g=f(); where g is global and f updates it
can have unexpected results - but I think a "legal" interpretation of
the standard would allow my "clear before write" "optimization" even if
no compiler writer would actually take advantage of it)
But in my example above either d[1] gets updated exactly once or there
_must_ be an sequence point between the two updates. In this instance
you seem to have chosen my interpretation of previous and next sequence
point where a sequence point that occurs in time between two other
sequence points is not necessarily previous to one and after the other.
((*f(0))++, p=f(1), (*p)++) + ((*f(2))++, q=f(3), (*q)++)
also has undefined behavior, for the same reason.
This is completely different. If you think this is even remotely the
same as my example then you haven't understood the subtleties of my
code. Its obvious that there doesn't have to be _any_ sequence point
between the (*p)++ and the (*q)++ regardless of the evaluation order.
I had thought that we had at least got to the point where if there are
three sequence points S(0) < S(1) < S(2) (where < denotes a time
ordering) then we were debating whether the standard states that S(1)
is the next sequence point to S(0) and the previous sequence point to
S(2) but now I'm not sure what you are arguing.
If you can convince me that the standard does say this then I accept
that x=(x=5,11) has defined behaviour, as does my example above[1]. But
your "((*f(0))++, p=f(1), (*p)++) + ((*f(2))++, q=f(3), (*q)++)" still
has undefined behaviour.
Tim.
[1] defined here means my code can output 0 or 1 but nothing else.