0

I have two CPU's. One 32 bit and another 64 bit. We have a piece of C++ code like the following:

typedef std::bitset<16> MyBits;

typedef struct t_MyStruct_16 {
    uint32_t first;
    int16_t second;
    __attribute__((__aligned__(8))) MyBits st;
} MyStruct_16;

typedef struct t_MyStruct_12 {
    uint32_t first;
    int16_t second;
    MyBits st;
} MyStruct_12;

Is it safe to use sizeof to calculate the size of the structure for both processors 32 and 64 bit ?? What about the padded stuff, is it going to influence the behavior of the code if I do bit wise operations ?

Thank you.

Yore
  • 384
  • 1
  • 4
  • 18
  • 2
    What do you mean safe? It's not going to kill you. – stark Jun 22 '17 at 13:36
  • I'm saying, if I for example, calculate a Hash from this bitset st, am I going to get different results for 32 and 64 bits or I will get the same for both?? – Yore Jun 22 '17 at 13:39
  • `sizeof` includes the padding that would be added if you create an array of the type of objects. – stark Jun 22 '17 at 13:41
  • typedef struct is a C relict. Don't use it in C++. –  Jun 22 '17 at 13:42
  • I know sizeof includes the padding. Maybe my question is not clear. Question is: Is sizeof for both structures bringing the same result (16 for the first and 12 for the second on both processors 32 and 64 bits ? ). – Yore Jun 22 '17 at 13:49

1 Answers1

1

In C++, padding is always added to met the alignment requirements of a data member. So the question can be rephrased as, "is alignof(T) the same for 32-bit and 64-bit` builds?"

In general, the answer is no. Compiling your example with gcc7 (linux), I get alignof(MyBits) equal to 8 on 64-bit builds, and 4 on 32-bit builds.

Since the alignment of a POD struct is the same as the alignment of the member with the highest alignment, and sizeof(T) must always be a multiple of alignof(T), you get that sizeof(MyStruct_12) is 16 on 64-bit builds, instead of 12.

A possible solution is to force the alignment (using alignof or __attrbitue__((aligned))) on every single member.

An easier solution, if you are using gcc, is to use #pragma pack(push) with a forced alignment value. For example:

#pragma pack (push, 4)
typedef std::bitset<16> MyBits;

typedef struct t_MyStruct_16 {
     uint32_t first;
     int16_t second;
     MyBits st;
} MyStruct_16;

typedef struct t_MyStruct_12 {
    uint32_t first;
    int16_t second;
    MyBits st;
} MyStruct_12;

#pragma pack(pop)

This forces the maximum alignment on every member to 4, which should work on both 32-bit and 64-bit builds.

sbabbi
  • 11,070
  • 2
  • 29
  • 57