0

I was testing a class alignment and found strange behavior. I tested it with VS2012 compiler setting 4 and 8 bytes alignment setting but in each case output is same.

class Alignemnt{
public:
    Alignemnt():a(){}
    int a;
};

class Alignemnt_1{
public:
    int a;
    char array[2];
};

class Alignemnt_2{
public:
    int a;
    char array[2];
    int x;
};

std::cout <<  "Sizeof(Alignemnt)   :" <<sizeof(Alignemnt) << std::endl;
std::cout <<  "Sizeof(Alignemnt_1) :" <<sizeof(Alignemnt_1) << std::endl;
std::cout <<  "Sizeof(Alignemnt_2) :" <<sizeof(Alignemnt_2) << std::endl;

Every time output is:

Sizeof(Alignemnt)   : 4

Sizeof(Alignemnt_1) : 8

Sizeof(Alignemnt_2) : 12

I think, Alignemnt_2 size should be 16 byte.

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
CrazyC
  • 1,840
  • 6
  • 39
  • 60
  • 1
    So, what is your question? Seems to me like the compiler is doing just fine? – danielschemmel Jan 29 '15 at 07:39
  • I think, Alignemnt_2 size should be 16 byte. – CrazyC Jan 29 '15 at 07:42
  • int would typically be 4 byte aligned. char[2] is only a 2 byte object. You get a 12 byte size because the first int takes up 4 bytes, the second object takes up 2 bytes, and the third one needs to be 4 byte aligned. – Charlie Jan 29 '15 at 07:44
  • 2
    @TonyD Size is a multiple of alignment, therefore alignment influences size. And this is not even talking about what *member* alignment does to the size of the containing object. – danielschemmel Jan 29 '15 at 07:44
  • Maybe he should try compile more tests! After some light reading, I was thinking, maybe the Visual Studio compiler optimizes the data storage in a special way? – CinchBlue Jan 29 '15 at 07:53
  • It strikes me that I don't know what settings you're using or how they play between objects, vs struct members. If the struct members are required to be 8 byte aligned, then #2 would need to be 24 bytes (or 20 bytes), but if the alignment is at the object/memory allocation level, then it doesn't change the size of your struct at all. – Charlie Jan 29 '15 at 07:59
  • A little bit offtop: you can use `struct` instead of `class` for testing reasons to save your time with avoiding printing `public` keyword – borisbn Jan 29 '15 at 08:17

3 Answers3

2

I assume you are referring to the /Zp switch, which lets you control maximum struct member alignment:

When you specify this option, each structure member after the first is stored on either the size of the member type or n-byte boundaries (where n is 1, 2, 4, 8, or 16), whichever is smaller.

Since you are not using a struct member with an alignment of more than 4 bytes (sizeof(int) and alignof(int) is both 4), all settings of 4 bytes and above will lead to exactly the same behavior.

If you want to specify the exact alignment of a structure member, consider using the standard C++ alignas which allows you to specify the exact alignment a member is supposed to have (VS 2012 should support it iirc).

See the result of using alignas.

danielschemmel
  • 10,885
  • 1
  • 36
  • 58
0

Alignment shouldn't change the size of your object, just the starting address of the objects. For instance, an 8 byte aligned object could be at address 0x100000 or 0x100008, or really any address ending in 0 or 8 when written in hex but not 0x100004.

Charlie
  • 1,487
  • 10
  • 9
  • I don't agree on it. alignment is related to the padding which alter the size of object. – CrazyC Jan 29 '15 at 07:42
  • Additionally the size of the object will be a multiple of its alignment. – danielschemmel Jan 29 '15 at 07:45
  • Yes. @gha..st. Alignment always yield the size of object to multiple of the setting. Here I made it 8 byte so instead of 12 it should be 16. – CrazyC Jan 29 '15 at 07:47
  • The size is not impacted by the alignment. Efficiency of packing is affected by alignment, but the bytes required to store the object are not. For instance, if I pack an object that needs to be 8 byte aligned next to something that doesn't care, there's no need for padding. – Charlie Jan 29 '15 at 07:47
  • @Charlie Unless you are talking about an overaligned type, have a look at [this example](https://ideone.com/clqxvE) that does exactly that: Pack an 8-byte aligned and sized object next to one with 1 byte alignment and size. The size changes from 9 bytes to 16 bytes when changing the alignment of the first member. – danielschemmel Jan 29 '15 at 08:08
  • @gha.st I was thinking something on the lines of whether the alignment applies at the struct level or the (i.e. the struct can be 8 byte aligned, but the allignment doesn't follow to the members) vs member alignment - alignas applied to the struct level vs alignas applied to each element. – Charlie Jan 29 '15 at 08:28
0

No.

Aligment 2 is fine.

You have 2 chars next to each other, that means you have 2 out of 4 bytes used. The packing will align it to 4 bytes, and then you will end up with 4 + 4 +4 .

If you want to end up to 16 you can try the following declaration :

 {
      char a;
      int b;
      char c;
      int d;
 }
MichaelCMS
  • 4,703
  • 2
  • 23
  • 29
  • @CrazyC Any reason for the downvote ? Is there anything I stated not true ? or you just like downvoting for the sake of downvoting ? – MichaelCMS Jan 29 '15 at 08:06
  • @CrazyC ah, sorry. I thought you downvoted . However, I would still like to know why the downvoter downvoted ... – MichaelCMS Jan 29 '15 at 10:18