This is the mail archive of the gcc-help@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: GCC aliasing rules: more aggressive than C99?


[ redir to gcc-help ]

On 01/03/2010 05:46 AM, Joshua Haberman wrote:
> The aliasing policies that GCC implements seem to be more strict than
> what is in the C99 standard.  I am wondering if this is true or whether
> I am mistaken (I am not an expert on the standard, so the latter is
> definitely possible).
> 
> The relevant text is:
> 
>   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
> 
> To me this allows the following:
> 
>   int i;
>     *pu = (union u*)&i;
>   printf("%d\n", pu->x);

I do not believe that this is allowed.  A union of type

   union u { int x; }

is not compatible with the type int.  It might have greater alignment,
it might be larger, and so on.  We do know that a pointer to a union
can be converted to a pointer to each of its members and vice versa.
But, and this is crucial, *that does not mean they are compatible
types*.

> In this example, the object "i", which is of type "int", is having its
> stored value accessed by an lvalue expression of type "union u", which
> includes the type "int" among its members.
> 
> I have seen other articles that interpret the standard in this way.
> See section "Casting through a union (2)" from this article, which
> claims that casts of this sort are legal and that GCC's warnings
> against them are false positives:

>   http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html

It's wrong.

You need to look at the standard's own definition of what constitutes
a compatible type.

<< 1 Two types have compatible type if their types are the
same. Additional rules for determining whether two types are
compatible are described in 6.7.2 for type specifiers,

...

6.7.2.1

A pointer to a structure object, suitably converted, points to its
initial member (or if that member is a bit-field, then to the unit in
which it resides), and vice versa.>>

Rather than reading dubious web sites, you need to refer to the
standard itself when trying to understand C.  There have been several
attampts to summarize the standard, and as far as I'm aware they are
all unreliable.

So please don't believe me: believe the standard.

Andrew.


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