This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]