Consider these two cases :
struct customType
{
dataType1 var1;
dataType2 var2;
dataType3 var3;
} ;
customType instance1;
// Assume var1, var2 and var3 were initialized to some valid values.
customType * instance2 = &instance1;
dataType1 firstMemberInsideStruct = (dataType1)(*instance2);
class CustomType
{
public:
dataType1 member1;
dataType2 member2;
retrunType1 memberFunction1();
private:
dataType3 member3;
dataType4 member4;
retrunType2 memberFunction2();
};
customType object;
// Assume member1, member2, member3 and member4 were initialized to some valid values.
customType *pointerToAnObject = &object ;
dataType1 firstMemberInTheObject = (dataType1) (*pointerToAnObject);
Is it always safe to do this ?
I want to know if standard specifies any order of storage among -
- The elements inside a C structure.
- Data members inside an object of a C++ class.
9.0.7
9.2.14
9.2.20
It's not always safe to do so. If the classes have
virtual
methods, it most definitely is not. Data members are guaranteed to appear in the same order for the same access level chunk, but these groups can be reordered.In order to be safe with these type of casts, you should provide a conversion constructor or a cast operator, and not rely on implementation details.
Typically in a C struct members are stored in the order that they are declared. However the elements must be aligned properly. Wikipedia has a good example of how this works.
I will re-iterate here:
If you have the following struct
padding will be inserted in between differing data types in order to assure the proper byte-alignment.
char
s are 1-byte aligned,short
s are 2-byte aligned,int
s are 4-byte aligned, etc.Thus to make
Data2
2-byte aligned, there will be a 1-byte padding inserted betweenData1
andData2
.It is also worth mentioning that there are mechanisms that can change the packing alignment. See #pragma pack.
C99 and C++ differ a bit on this.
The C99 standard guarantees that the fields of a struct will be laid out in memory in the order they are declared, and that the fields of two identical structs will have the same offsets. See this question for the relevant sections of the C99 standard. To summarize: the offset of the first field is specified to be zero, but the offsets after that are not specified by the standard. This is to allow C compilers to adjust the offsets of each field so the field will satisfy any memory alignment requirements of the architecture. Because this is implementation-dependent, C provides a standard way to determine the offset of each field using the
offsetof
macro.C++ offers this guarantee only for Plain old data (POD). C++ classes that are not plain old data cannot be treated like this. The standard gives the C++ compiler quite a bit of freedom in how it organizes a class when the class uses multiple inheritance, has non-public fields or members, or contains virtual members.
What this means for your examples:
This line is okay only if dataType1, dataType2, and dataType3 are plain old data. If any of them are not, then the customType struct may not have a trivial constructor (or destructor) and this assumption may not hold.
This line is not safe regardless of whether
dataType1
,dataType2
, anddataType3
are POD, because theCustomType
class has private instance variables. This makes it not a POD class, and so you cannot assume that its first instance variable will be ordered in a particular way.