On Tue, 20 Mar 2007, Tobias Ulmer wrote:

 ....

> /*
>  * You assume that the in memory representation of an
>  * unsigned [2] looks exactly like unsigned long long and you
>  * expect to access the valid initialized memory of x by
>  * dereferencing p.
>  *
>  * These assumptions are all wrong.
>  */

 ....

Indeed.

The error is very similar to making assumptions about how
the internal structure of x, p and c might relate in the
commonly seen:

        union roach_motel {
                unsigned long long x;
                unsigned int p[2];
                unsigned char c[8];
        } foo;  /* draws bugs */

We haven't even scratched the surface of the subtle joys of
big-endian addressing schemes (note the plural) or alignment
requirements in some architectures.

> Your program is invalid. Gcc has all rights to fuck it up,
> -omg-optimized or not.

It's not strictly invalid, it just doesn't follow the programmer's
intent.  This is the most difficult sort of bug to find for the
original programmer ("code blindness"), but a stranger can find it
more easily.  Now if we take code like the example program, and
intersperse a few thousand lines of other code, and break it all
up over a hundred functions (and files, and bury the declarations
about 5 deep in include files), put half the bug in a library, we
have the makings of a Windoze-grade nightmare. Add some conditionals,
we can write it so that the problem with uninitialized "c" only
shows up one run in a thousand.  0xDEADBEEF comes to mind...

> Casts are basically syntactic sugar for "(i know what i'm doing, now
> shut up and stop complaining)". Remove the (void *) and compile with
> -Wall.

Some casts are "READ MY MIND, DAMN IT!".  In this case, we notice
that cc -O2 and cc -O3 have different psychic skills.

I murmur again about "alignment issues", which don't exist for
the i386 architecture, as far as I know, except as an optimization.
(And certain obscure features of the PeeCee like DMA.)

The C standard is full of references to alignment. 
In some architectures, I believe   
        void *p,*q;  p=(long *)1;  q=(char *)1;  
        p==q will be false.

To the OP:  you can't do both bit-wise manipulation and arithmetic
and expect the results to be always what you think.  Besides "endian"
issues and "alignment" issues, there can be questions of arithmetic
(2s-complement, 1s-complement, and others).  The PeeCee has blinded
many to the rich diversity of hardware possibilities.

Sometimes you just have to drag out the assembler.
        
Dave
-- 
     Resistance is futile.  You've already been assembled.

Reply via email to