|
Boost : |
From: David Abrahams (abrahams_at_[hidden])
Date: 2000-08-24 08:41:05
From: "Bill Wade" <bill.wade_at_[hidden]>
> You can certainly find an alignment that "works" (although I don't believe
> there is a portable way to find the minimum alignment that works).
However
> even if you do so the code using Report is not strictly portable. This is
[sic] ^^^^^^
> the (in)famous "struct hack." Conforming compilers may perform bounds
> checking on arrays and pointers.
>
> myrule.symbols[2];
>
> and even
>
> myrule.symbols+2;
>
> invoke undefined behavior even if the memory is available and properly
> aligned.
Yikes!
> For instance an optimizing compiler "knows" that
> myrule.symbols[i] = "hello";
> is undefined if 'i' is not zero. As a result, the compiler is allowed to
> assume 'i' is zero and generate faster and smaller code that does not do
the
> pointer math.
>
> In range-checking implementations that I've seen, the range-checking gets
> turned off when the pointer is involved in a cast:
>
> struct Rule
> {
> unsigned long cost;
> const void* action;
> const char** symbols(){ return (const char**) (&action+1); }
> };
Okay, but is this still a POD? And if action were of type char instead of
const void*, then your symbols() array would most likely be misaligned.
It seems to me that ((const char**)symbols)[2] has to work, in any case. The
reasoning? The compiler is not allowed to perform bounds checking on a raw
pointer, and the expression above creates a temporary raw pointer before
indexing it. Am I missing something?
-Dave
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk