The following seems a gcc 3.0 bug, not sure it was fixed in gcc 3.01.
See the assembly generated with -O3 for the following code:
--------------------------------------------------------------
inline static long QInt(double inval)
{
        long *l;
        char *c = (char*) &inval;
        inval = 68719476991.99;
        l = (long*) (c+2);
        return *l;
}
int main(void)
{
        printf("%lu\n", QInt(OFFENDING_VALUE));
        return 0;
}
---------------------------------------------------------------
the above function is compiled as:
        .file   "test2.c"
        .section        .rodata
.LC0:
        .string "%lu\n"
        .text
        .align 16
.globl main
        .type   main,@function
main:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $48, %esp
*       movl    $16776561, -32(%ebp)
*       movl    -30(%ebp), %eax
*       movl    $1110441984, -28(%ebp)
        pushl   %eax
        pushl   $.LC0
        call    printf
        addl    $16, %esp
        movl    %ebp, %esp
        xorl    %eax, %eax
        popl    %ebp
        ret
.Lfe1:
        .size   main,.Lfe1-main
        .ident  "GCC: (GNU) 3.0"
Note the line I marked with "*".
The double var is 8 byte, it is loaded
moving two 32 bit words in the -32 and -28 offset.
Unfortunatelly with -O3 the "*l" value get
computed between the two 'movl', and not after
the second movl.
This code is really unsane anyway but this seems
a clear gcc 3.0 bug.
I hope that the gcc folks here may report the
problem if not already known.
I didn't tested it but maybe the same problem
exists with other 8 byte types like 'long long'.
regards,
antirez
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/