Re: Clarification on Gcc's strict aliasing rules

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 11/12/2010 11:45 AM, Francis Moreau wrote:
... elision by patrick
No.
    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 types.46) 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:

union u{
   int i;
   double p;
} thisistheunion.

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 foo(thisistheunion, thisistheunion.i) // 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.

Thanks



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux