Reputation: 9416
While working on a legacy projectr I came across the following pattern: a POD struct is used to transfer data over the network.
struct PODType {
// some data
int data;
};
On the receiver side, the data is received into an object of the POD type. Later on, a class is derived from the PODType and the received object is casted with a C-style cast into the derived class to use some methods accessing the data.
class DerivedFromPOD: public PODType {
public:
// some methods
int f(int x) {return data+x;}
protected:
// some methods
};
PODType pod;
receive(&pod);
DerivedFromPOD* d = (DerivedFromPOD*)&pod;
int i = d->f(10);
The derived class has public and protected methods, so it is not a POD anymore. I know that this is an abuse of inheritance, but it has been in the code base for a long time.
I am wondering if that is guaranteed to work from a standard point of view (C++03 or C++98). The derived class does not have any own data members or virtual functions, but I am not sure if it guaranteed that the memory layout is identical given that one is POD and the other is not. Is the compiler forced to arrange DerivedFromPOD such that d.data
's address is identical to the address of an object d of DerivedFromPOD type, as it is for the POD base-class?
Upvotes: 2
Views: 1107
Reputation: 1907
A DerivedFromPOD*
pointer can be cast safely into a PODType*
pointer.
So we are assured that the layout of the inherited PODType
in memory is the same.
However, when casting in the opposite direction, DerivedFromPOD
can be composed in memory with some compiler data, then the PODType
data, then some additional compiler data.
If you're using the C-style cast, or static_cast<>
for this cast, the compiler will assume you know what you're doing and adjust the pointer address so that the PODType
part of the DerivedFromPOD
will correctly point to the good area.
However don't try to use methods that will access other data from DerivedFromPOD
as they won't be correct in memory.
In particular, don't use any virtual methods as the VMT (Virtual Method Table) is not there.
Upvotes: 1
Reputation: 153977
It's certainly not guaranteed to work in general (try adding a virtual function to the derived class), and is formally undefined behavior. (I also don't see how a struct
can be used to help transfer data over the network. Different machines will represent it differently.)
Upvotes: 2