This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: ISO Aliasing rules question
- From: Michael Matz <matz at suse dot de>
- To: <law at redhat dot com>
- Cc: <gcc at gcc dot gnu dot org>
- Date: Fri, 21 Feb 2003 20:16:29 +0100 (CET)
- Subject: Re: ISO Aliasing rules question
Hi,
On Fri, 21 Feb 2003 law at redhat dot com wrote:
> struct s1 { double d; };
> struct s2 { double d; };
>
> double f(struct s1 *a, struct s2 *b)
> {
> a->d = 1.0;
> return b->d + 1.0;
> }
>
> int main()
> {
> struct s1 a;
> a.d = 0.0;
> if (f (&a, (struct s2 *)&a) != 2.0)
> abort ();
> return 0;
> }
>
>
> Does this code produce undefined behavior according to ISO standard,
> particularly in regards to aliasing issues.
I asked myself also repeatedly similar things. Is 'a->d' a whole object
or not? If yes, then 'a->d' and 'b->d' alias because they have the same
type. I not, i.e. they are only part of the objects *a and *b, then they
can not alias, because as you notice 'struct s1' and 'struct s2' are not
compatible types as defined in 6.2.7 #1.
> Thus the variables a & b in function f can't refer to the same object
> as they are not type compatible.
Well, the aliasing rules only constrain how you can _access_ the storage,
not how many and which references you can have to it. I.e. a and b are
allowed to refer to the same storage, just the access later would be
non-conforming. But the basic question is, if a->b constitutes an access
to a 'double' object, or to a 'struct s1.double' object. And about that I
wondered too repeatedly ;-) 6.5.2.3 says the type of an 's->x' expression
is that of member 'x' (with added qualification), so I guess, that a->b
and b->d _do_ alias each other (both types are double).
Ciao,
Michael.