Re: [OT] Re: Questions about pointers to objects and pointers to functions
- From: Tim Rentsch <txr@xxxxxxxxxxxxxxxxxxx>
- Date: 04 Oct 2005 10:24:54 -0700
"S.Tobias" <siXtY@xxxxxxxxxxxxxxxxxxxxxxxxxx> writes:
> Tim Rentsch <txr@xxxxxxxxxxxxxxxxxxx> wrote:
> > "S.Tobias" <siXtY@xxxxxxxxxxxxxxxxxxxxxxxxxx> writes:
> >> Tim Rentsch <txr@xxxxxxxxxxxxxxxxxxx> wrote:
> >> > "S.Tobias" <siXtY@xxxxxxxxxxxxxxxxxxxxxxxxxx> writes:
>
> ...
> >> >> a = *(TYPEA volatile*)&b;
> >> >> //take the address of b, convert it to ptr to `volatile TYPEA',
> >> >> //dereference, take value and put into `a'
> >> >> //lvalue is type `volatile TYPEA'... hmm... nooooo, of course
> >> >> //it can't mean b here, let's read what that object contains,
> >> >> //and update b later...
> ...
>
> >> The decision which object
> >> _may_ be accessed can be based only on the type of lvalue and
> >> effective type of the object, and I believe that this optimization
> >> above is allowed.
> >
> > What I think you're saying is that, even though the compiler
> > knows that the casted address refers to 'b', the rule in the
> > Standard about effective type allows the compiler to forget
> > that it does. And that's right; the Standard does allow
> > that.
> >
> > But no actual compiler is going to do that. When optimizing, a
> > compiler always wants to use the best information available,
> > because that information might enable further optimization. So
> > the compiler is going to remember that the casted address points
> > to 'b' even though it's "gone through" the cast.
>
> [snip]
>
> >> Since all information is in one expression, it's easy to infer that
> >> in this case object `b' is going to be accessed. However, a compiler
> >> need not be that wise. Have you tried this with DS9000?
> >
> > Not a relevant question, since we agree on what judgment the
> > Standard renders in such cases. Rather, the question is what do
> > actual compilers do. So if you want to make your case, look for
> > an actual compiler where the generated code for an assignment
> > statement
> >
> > a = * (TYPEA volatile*) &b;
> >
> > is along the lines you suggest.
>
> Okay, I guess I'm talking just theory, you're making a practical point.
That seems like a fair summary.
> I don't really know what compilers do (and I don't especially want to).
> I once had this code, where I unwisely tried to save on temporary
> variables:
>
> int Mem_dosomething(const void *s1, const void *s2) {
> for (; *(char*)s1 == *(char*)s2; ++*(char**)&s1, ++*(char**)&s2) ;
>
> and gcc gave the warning (in -O2 mode):
> t.c:3: warning: dereferencing type-punned pointer will break
> strict-aliasing rules
> What this says to me is that the implementors have done something
> "clever" and warn me that the "lvalue cast" construct is not
> safe, despite that char* and void* have the same representation.
That's possible. I think it's more likely to indicate an aggressive
warning check than to reflect whether the compiler considers the
generated code doesn't match the intention.
> I don't actually know if the warning is really applicable at that
> particular point, or is merely printed by default before the compiler
> even considers whether it's going to do an optimization at all.
> Better safe than sorry. I corrected above code to:
>
> const unsigned char *c1 = s1, *c2 = s2;
> for (; *c1 == *c2; ++c1, ++c2) ;
>
> which is always portable.
It seems clear that the second writing is preferable to the first.
.
- Prev by Date: Re: disable stdout buffering ?
- Next by Date: Re: [OT] Re: Questions about pointers to objects and pointers to functions
- Previous by thread: parsing #define in a code
- Next by thread: Re: [OT] Re: Questions about pointers to objects and pointers to functions
- Index(es):
Relevant Pages
|