I have the following casting problem when my data structure sSpecificData contains a field of type tm:
typedef struct
{
unsigned char data[10000];
} sDataBuffer;
typedef struct
{
int m_Id;
sDataBuffer m_Data;
} sData;
typedef struct {
int m_value1;
int m_value2;
tm m_Date;
} sSpecificData;
const int SPECIFIC_SVC_DATA_SIZE = sizeof(sSpecificData);
typedef struct {
int m_Id;
sSpecificData m_Data;
} sMyData;
int main(void)
{
sData svc;
sMyData* ptr1 = (sMyData*) &svc;
sSpecificData* ptr2;
ptr2 = (sSpecificData*) &svc.m_Data;
ptr1->m_Data.m_value1 = 90;
ptr1->m_Data.m_value2 = 80;
cout << ptr1->m_Data.m_value1 << endl;
cout << ptr1->m_Data.m_value2 << endl;
cout << ptr2->m_value1 << endl;
cout << ptr2->m_value2 << endl;
return 0;
}
Without the field “tm m_Date;” as part of the sSpecificData, the output is correct:
90
80
90
80
With the field “tm m_Date;” as part of the sSpecificData, the output is wrong:
90
80
0 <-- !
90 <-- !
Is there any idea why my example doesn’t work when there is field of type tm as part of the sSpecificData?
Thanks!
this has to do with structure packing. by adding the
tmfield to the sSpecificData, you are changing it from a structure that has a natural alignment of int (4 bytes), to something that has a natural alignment of what appears to be 8 bytes.so with
tmas part ofsSpecificData, the structuresMyDatais effectively thisthis explains what you are seeing. To fix this, you can add an explicit padding value to sMyData AND to sData.
Or you can use
#pragma pack(4)(if your c compiler supports it) to force the padding to be left out of sMyData, but this will result intmbeing misaligned which isn’t a good idea. see this related question.a very similar question came up today about C#, but the issues are the same, (the syntax for specifying packing is different though)
Size of structures in .NET