Kai-Uwe Bux said:
Well, let's have a look at the wording of the standard:
[5/4]
Except where noted, the order of evaluation of operands of
individual operators and subexpressions of individual
expressions, and the order in which side effects take place,
is unspecified.53) Between the previous and next sequence
point a scalar object shall have its stored value modified
at most once by the evaluation of an expression. Furthermore,
the prior value shall be accessed only to determine the value
to be stored. The requirements of this paragraph shall be met
for each allowable ordering of the subexpressions of a full
expression; otherwise the behavior is undefined.
Now, if the standard just dropped the line last 5 words, the
clause would still specify what a well defined program looks
like. Just the compiler would be required to issue an error
if the shall-clause is violated.
To detect this reliably is not so simple:
int p;
void foo(int *q)
{
p = *q++;
}
int main()
{
int a = 0;
switch( getchar() )
{
case 'a': foo(&p, &a); break;
case 'b': foo(&p, &p); break;
}
}
Then there is only a problem if the user types 'b'.
C99 has added a partial solution called 'restrict' but
I think that does not solve the problem in this particular
case.
I cannot see a simple way that the compiler can generate an
error for the above code, but still permit a good range of
legal code. It seems to me that the only solution would be
for the compiler to store 'metadata' with foo, that &a
must not be equal to p, and to trap any possible path of
execution that gives that result (including casting integers
to pointers). This information must also be checked across
compilation units and across libraries (it would certainly
require a new C ABI so that libraries such as GLIBC could
keep track of restrictions). This seems too restrictive to me
and it would cripple many of the uses that C is currently
put to.