Boost logo

Boost :

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.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk