Clarification on Gcc's strict aliasing rules
Fri Nov 12 23:04:00 GMT 2010
On 11/12/2010 11:45 AM, Francis Moreau wrote:
... elision by patrick
> t.d = 3.0;
> i = t.i;
> is well defined in C.
> Again, what's ambiguous is the example given by the GCC man:
> int *ip;
> t.d = 3.0;
> ip =&t.i;
> return *ip;
> which produces code that might or not work.
> 6.5p7 lists this as a possible alias case and I can't find any rule in
> the standard that could invalidate it.
Well, 6.2.5 Types
21 Arithmetic types and pointer types are collectively
called scalar types. Array and
structure types are collectively called aggregate
46) Note that aggregate type does not include
union type because an object with union type can only
contain one member at a time.
So technically accessing a different member is
undefined behavior, but realistically you'll get
"something", and this is how people do things like deal
with endian issues without running afoul of strict
aliasing issues. int vs double is a bit of a stretch,
allow though you might imagine a struct with bit fields
that let you look at the different parts of the
double. (Again, I know, accessing in this way is
undefined behavior. But see 6.2.6
In general, you're looking at 6.5 differently than the
people that wrote it. 6.5 is a set of rules for
compiler writers to know when things might alias so
that they don't do optimizations that don't make
sense. For example if lvalues t1 and t2 can alias,
then you can't reorder accesses if the value of the
object referred to by one of them is changed. You
can't pull an apparently loop invariant assignment to
one of them out of a loop if an assignment to another
is also in a loop. You can't replace the use of one by
a constant assigned to it if intervening assignments
are made to the other. 6.5p7 is meant for things like:
void foo(u& theunion, int & theint)
// inside here theunion.i and theint have to be
considered as potentially aliasing
// since we could have been called like
// don't do any optimizations that might break if
this is true.
... lots of most excellent code ...
What you're really looking at is type punning not
aliasing. Footnote 94 is interesting:
94) If the member used to access the contents of a
union object is not the same as the member last used to
store a value in the object, the appropriate part of
the object representation of the value is reinterpreted
as an object representation in the new type as
described in 6.2.6 (a process sometimes called ââtype
punningââ). This might be a trap representation.
In general though, if you want to access something as
other than it's lvalue type, the ONLY supported way
according to the standard is through access as chars.
> So either GCC is not conformant in this regard or I'm missing something.
More information about the Gcc-help