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: Tricky(?) aliasing question.


Sergei Organov writes:
 > Andrew Haley <aph@redhat.com> writes:
 > 
 > > Sergei Organov writes:
 > >  > Andrew Haley <aph@redhat.com> writes:
 > >  > 
 > >  > > Sergei Organov writes:
 > >  > >  > Ian Lance Taylor <iant@google.com> writes:
 > >  > >  > > Sergei Organov <osv@javad.com> writes:
 > >  > >  > >
 > >> >  > int float_as_int()
 > >  > >  > {
 > >  > >  >   h1.f = 1;
 > >  > >  >   H0 h0 = *(H0*)&h1.f; // Should be OK? No, it is not?!
 > >  > >
 > >  > > I don't think this is OK.  Per C99, you can cast to the element type
 > >  > > from the struct or vice versa, but you can't cast from one struct type
 > >  > > to another via the first element.
 > >  > 
 > >  > There is no word "casting" in the definition of the aliasing rules in
 > >  > C99. It talks about accessing of object through an lvalue of compatible
 > >  > type. In this example I access stored value of object "h1.f"
 > >
 > > No, that's not what the code above does.  You're accessing an object
 > > of type h1 through an lvalue of type h0.  Accessing h1.f would have
 > > been perfectly OK, but that's not what the code above does.
 > >
 > > Look at it again:
 > >
 > >    H0 h0 = *(H0*)&h1.f;
 > >
 > > The LHS of this assignment is of type h0.
 > 
 > Yes.
 > 
 > > The RHS is an object of effective type h1.  The fact that you're going
 > > via a pointer cast to its first member is neither here nor there.
 > 
 > So "h1.f" is not an object?

This is too silly for words.

 > If it is not, it brings us back to the validity of my boo()
 > function from the initial post, for which 2 persons (3 including
 > me) thought it's OK:
 > 
 > S s;
 > int boo()
 > {
 >   s.i = 20;
 >   // Accessing 's' of type 'S' through 'int'. Is it aliasing rules
 >   // violation?  Maybe yes, but on the other hand this could be
 >   // considered as accessing 's.i' of type 'int' through 'int' that
 >   // should be OK from C99 standard POV?
 >   *(int*)&s = 10;
 >   return s.i;
 > }
 > 
 > Do you think this one is OK then?

Yes.  The standard says it's OK.  

You can convert a pointer to a struct to the type of its first member,
and back to a pointer to the original struct and the pointer will
still be valid.  What you can't do is use that converted pointer to
access an object of incompatible type.

 > Anyway, I can rewrite the float_as_int() so that it will access plain
 > float f:
 > 
 > float f;
 > int float_as_int()
 > {
 >   h1.f = 1;
 >   H0 h0 = *(H0*)&f; // Should be OK? No, it is not?!

No.  The types have to be compatible.  If f were of type h0, this
would be OK.  But f is of type float, so it isn't.

 >   return h0.i;
 > }
 > 
 > Does it change anything in your reasoning?

No.

Andrew.


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