Andrew Haley <[EMAIL PROTECTED]> writes: > Sergei Organov writes: > > Andrew Haley <[EMAIL PROTECTED]> writes: > > > > > Sergei Organov writes: > > > > Andrew Haley <[EMAIL PROTECTED]> writes: > > > > > > > > > Sergei Organov writes: > > > > > > Ian Lance Taylor <[EMAIL PROTECTED]> writes: > > > > > > > Sergei Organov <[EMAIL PROTECTED]> 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.
Sorry, I don't understand the meaning of this phrase. I thought I have accessed object "h1.f" of type float. Didn't I? Anyway, this is not that essential for the discussion, provided accessing bare float variable is not permitted in your opinion as well. > > 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. OK, I think I see your point here. Due to the fact that 'S', as declared, has the first field of type 'int', the 'S' and 'int' types are compatible, so I simply access stored value of the object 's' through a compatible type 'int', right? > > Anyway, I can rewrite the float_as_int() so that it will access plain > > float f: > > > > typedef struct { > > int i; > > float f; > > } H0; > > > > float f; > > int float_as_int() > > { > > 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. I agree the types 'H0' and 'float' are not compatible types. But the question is not about compatibility of types, -- the question is about violation (or not) of strict aliasing rules. If we come back to strict aliasing rules, then I will have to refer once again to already cited place in the standard that says that I'm permitted to access an object not only through a compatible type, but also through a structure containing a field of compatible type (and there is no indication that those field should be the first one in the structure): An object shall have its stored value accessed only by an lvalue expression that has one of the following types: - a type compatible with the effective type of the object, [...] - an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union) Or are you saying that I don't violate strict aliasing rules, but instead some other rule from the standard? If so, then how to explain that GCC stops to "miscompile" the code when I add -fno-strict-aliasing option? Not that I insist on sane results of compilation of broken code, but it seems that GCC thinks it's violation of strict aliasing rules. -- Sergei.