$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Bill Wade (bill.wade_at_[hidden])
Date: 2000-08-24 11:52:10
> From: David Abrahams [mailto:abrahams_at_[hidden]]
> > struct Rule
> > {
> > unsigned long cost;
> > const void* action;
> > const char** symbols(){ return (const char**) (&action+1); }
> > };
>
> Okay, but is this still a POD?
Yes. The addition of a non-virtual member function (other than 'tors and
maybe assignment, I don't remember) is not enough to turn a POD struct into
a non-POD struct.
> And if action were of type char instead of
> const void*, then your symbols() array would most likely be misaligned.
Correct. In that case you'd need to do something extra to ensure alignment.
> 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?
The compiler is allowed to perform bounds checking on a raw pointer. I
don't think you can find anything in the standard that guarantees
void* x = new char[10];
(char*)x+20;
has defined behavior. On the other hand, for the struct hack the math on
the raw_pointer stays within a contiguous block of memory that you have
allocated. I think that means that you should be ok. However the standard,
in general, takes a dim view of casting a pointer between unrelated types.
Almost all implementations are much more forgiving than the standard.
int i;
assert(&i == (void*)(short*)(void*)&i);
I've never used an implementation that would trip the assert, but the
standard allows this to fail, and it probably invokes undefined behavior.