T
Tim Rentsch
Francis Moreau said:Tim Rentsch said:[...]
I don't think is can be so simple. What about:
u.b = 1.23;
int *ip = &u.a;
int i = *ip;
Is the access via *ip valid under strict aliasing rules? This is the
example in the gcc man page that is declared invalid, yet it seems to me
your requirements: "the lvalue is of type int, and the effective is also
of type int".
Do you mean under effective type rules, or under strict aliasing
rules? As far as I know 'strict aliasing' is defined by GNU/FSF
as part of gcc, and is more restrictive than the effective type
rules of C99 -- in other words, under 'strict aliasing' rules some
programs that are defined under the ISO standard would behave
other than as the ISO standard requires. So it's important
to know which one you are asking about.
Ok so it looks like we agree that the example given by GCC's man page
which is the same as the above one _is_ defined by the standard as a
valid alias case.
However it looks like the Standard doesn't handle the union special case
correctly when it comes to aliasing, since unions remove all
optimisations based on type:
union u { int a; double b; };
/* at that point int can alias double */
int *i;
double *d;
void foo(int *pi, double *pd) { ... }
int main (void)
{
union u u;
i = &u.a;
d = &u.b;
foo(i, d);
}
So 'strict aliasing' seems the correct thing to do.
Two comments:
1. In the context of discussing standard C, I
think it's better not to use the term "strict
aliasing" since it does not have a well-defined
meaning (not counting the meaning that "it's
whatever gcc takes it to mean").
2. The question you bring up is one where the
Standard itself is unclear. There are at least
four different questions, namely, (a) What
does the Standard actually say about this?;
(b) What do people generally take it to mean?;
(c) What did the members of WG14 intend the
Standard to require in this case (and that
is probably different for different members)?;
and (d) What semantics are most in keeping
with how the Standard describes the language
otherwise? As far as I know none of these
questions has a clear answer, so when you
ask about what is "the correct thing to do",
all I can say is it's not clear, even though
I don't know which question you are trying
to answer.
By the way, your example doesn't say whether
the complete union type is visible at the
point where the function foo() is defined,
and this will make a difference, at least in
some cases, in what behavior people expect for
this example.