Re: Structure mapping using reinterpret_cast.
* Olivier:
I would like to check if a certain technique can be used or whether
there is any entry in the standard that prohibits it explicitly. If I
recall correctly, the standard guarantees that two structures
containing the same starting data members can be mapped on one another
and these common members can be access without yielding undefined
behaviour.
That only applies to POD structures, and except for the first member it only
applies, in a restricted way, to access via unions, not to casting.
That is, given :
struct A { int a; int b; };
struct B { int c; };
the following code is guaranteed to work :
A a;
B &b = *reinterpret_cast<B *>(&a);
b.c = 12;
assert(a.a == b.c);
And this assert should never fail.
The above is formally guaranteed by ?9.2/17 and flatly contradicted by ?5.2.10
(in particular ?5.2.10/1 "No other conversion can be performed explicitly").
That is, the standard has a defect in this regard.
The standard is also in a sense incomplete about this in that it doesn't even
address the general case where a reinterpret_cast between POD class types is
safe, but just has the special case above tacked on, contradicting itself.
And given that the C++ standard is (1) defective (self-contradiction) and (2)
incomplete, the in practice is to rely on *understanding* layout and pointer
representations (in particular alignment), what it means at the machine code
level, and from that point of view the above is safe.
However, any argument about safety or otherwise of a reinterpret_cast between
POD structure types that invokes the C++ standard in a formal way, rather than
referring to its intention, is currently invalid, since it contradicts itself.
For half-formal justification (then talking about the /intention/ for the C++
standard) one might possibly go down the C standard. But I'm not sure whether
the C standard is any better than the C++ standard in this respect. One would
hope so, and perhaps someone will chime in about that.
By extension, if that is true, the following code should be guaranteed
to work :
#include <iostream>
// Base class containing the data.
class A
{
public:
A( int val = 0 ) : val_(val) { }
protected:
int get_value( ) const
{ return val_; }
private:
int val_;
};
// Interface class that uses A's data.
class B : public A
{
public:
int function( ) const
{ return get_value() / 2; }
};
// Another interface class that uses A's data.
class C : public A
{
public:
int function( ) const
{ return get_value() * 2; }
};
int main( )
{
A *a = new A(12);
B *b = reinterpret_cast<B *>(a);
std::cout << b->function() << "\n";
C *c = reinterpret_cast<C *>(a);
std::cout << c->function() << "\n";
delete a;
}
If this isn't the case, could anyone quote the entry in the standard
that states this code yields undefined behavior ?
?5.2.10/1 "No other conversion can be performed explicitly" and yours isn't
listed. Note that the above aren't POD types so ?9.2/17 does not apply.
Cheers & hth.,
- Alf
--
Due to hosting requirements I need visits to <url: http://alfps.izfree.com/>.
No ads, and there is some C++ stuff! :-) Just going there is good. Linking
to it is even better! Thanks in advance!
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]