This is the mail archive of the 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?


[oh my, coming late to this thread, I'm sorry about restarting it but I 
feel the urge to comment on some misconceptions I read, I believe ;-) ]

Commenting on the first mail where I think one subthread went down the 
wrong path:

On Tue, 5 Jan 2010, Andrew Haley wrote:

> On 01/05/2010 02:09 AM, Joshua Haberman wrote:
> > Erik Trulsson <ertr1013 <at>> writes:
> >> On Mon, Jan 04, 2010 at 08:17:00PM +0000, Joshua Haberman wrote:
> >>> The text you quoted does not contain any "shall not" language about
> >>> dereferencing, so this conclusion does not follow.
> >>
> >> It doesn't have to use any "shall not" language.  If the standard does not
> >> say that any particular action is allowed or otherwise defines what it
> >> does, then that action implicitly has undefined behaviour.
> > 
> > Section 6.5 does define circumstances under which converted pointers may
> > be dereferenced.
> No.  It says
> "An object shall have its stored value accessed only by an lvalue
> expression that has one of the following types:
> but
>  (union u*)&i
> is not a legal lvalue expression because the dereference is undefined
> behaviour.  You may only dereference a pointer as permitted by

I'm very sure this is a misunderstanding on your part, which then results 
in your discount of the other arguments.  It's really 6.5 that makes the 
above dereference invalid, not  You seem to interpret p7 
as somehow limiting what operations can be done with the converted 
pointer.  This is wrong.  Let's look at it in detail:

A pointer to an object or incomplete type may be converted to a pointer to 
a different object or incomplete type.

Ignore incomplete types, so let's assume we have a pointer P to an object 
type T (let's assume it points to object O of type T), and we convert it 
to a pointer P1 to object type T1:

P1 = (T1 *) P;

If the resulting pointer is not correctly aligned for the pointed-to type, 
the behavior is undefined.

Good good, let's assume this isn't the case, hence we invoke this 

Otherwise, when converted back again, the result shall compare equal to 
the original pointer.

Okay, this tells us the following:

P == (T *) P1;

_When_ converted back it's the same pointer (IOW it again points to O).  
It doesn't say the slightest about what other operations might be allowed 
on the pointer.  It restricts the possible outcomes of a back-conversion.  

That's all it says (the other sentences here deal with char types, let's 
ignore these too).

In particular, if alignment was correct, we have a pointer to object type 
T1.  Pointers to object types may be dereferenced and then yield a value 
or object-reference of type T1, if that pointer is valid ( p4), 
where pointer validity has several cases (not null, aligned enough, object 
lifetime must not have ended, and some other things which we'll come to in 
a moment).

In order to establish the existence of O1 (the up to now hypothetical 
object that P1 points to), and hence validity of P1, we really need to 
consult 6.5.  Only that one tells us when we may access the value in 
object O with the type typeof(O1).

At that point also the access "*(unsigned *)ptr-to-int" is valid (wondered 
about downthread).  Not because anything in the pointer conversion was 
valid (it is valid), but specifically because 6.5p7 (and nothing else) 
tells us so.

The original poster is not correct in believing that 6.5p7 only talks 
about dereferencing converted pointers (I think this was held to his 
disfavor downthread), it talks about _all_ accesses of values of objects, 
however you come to access them; converted pointers are just one case.

Having said all this, the original poster is correct that GCC doesn't 
implement C99 aliasing as written in the standard regarding unions.  We 
don't do so because we determined that this can't possibly have been the 
intent of the standard as it makes type-based aliasing relatively useless.


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