4

Here is a snippet:

#pragma pack(4)
struct s1
{
    char a;
    long b;
};
#pragma pack()

#pragma pack(2)
struct s2
{
    char c;
    struct s1 st1;
};
#pragma pack()


#pragma pack(2)
struct s3
{
    char a;
    long b;
};
#pragma pack()

#pragma pack(4)
struct s4
{
    char c;
    struct s3 st3;
};
#pragma pack()

I though sizeof(s4) should be 10 or 12. But it turns out to be 8. I am using Visual C++ 6.0. Could someone tell me why?

2
  • The reason why I thought sizeof(s4) is 10 based on:|c|Padding|Padding|Padding|a|Padding|b|b|b|b|. But the actual layout is |c|Padding|a|Padding|b|b|b|b|. Commented Nov 26, 2012 at 5:05
  • On your system, the sizeof(long) is 4. Thats why sizeof(s3) is 6 and sizeof(s4) is 8. Commented Nov 26, 2012 at 5:07

4 Answers 4

2
#pragma pack(2)
struct s3
{
    char a;
    long b;
};
#pragma pack()

So the packing alignment of s3 is 2, and its size is 1 (alignment 1) + 1 (padding) + 4 (alignment 2) = 6.

#pragma pack(4)
struct s4
{
    char c;
    struct s3 st3;
};
#pragma pack()

The packing alignment of s4 is 4, and its size is 1 (alignment 1) + 1 (padding) + 6 (alignment 2) = 8.

Note that #pragma pack doesn't "extra-align" anything with looser alignment requirements. It only reduces alignment, i.e. controls "packing" alignment.

Sign up to request clarification or add additional context in comments.

4 Comments

As the alignment of s4 is 4, It should be 1 + 3(padding) + 6 = 10. or 1 + 3(padding) + 6 + 2(padding) = 12.
@user1758245: No. All it means is that each member of it will require alignment no greater than 4. It doesn't mean that each member will have alignment requirement 4. Notice, after all, it's called pack and not align for a reason -- precisely because it controls packing, not alignment. __declspec(align(#)) might be what you need though.
user1758245: Why 3(padding)? The alignment of s3 is 2, so it only needs 1(padding) after char c.
I finally understand "pack" and "align". Thank you. And thank all those who have answered my question.
2

The documentation for #pragma pack(n) says that "The alignment of a member will be on a boundary that is either a multiple of n or a multiple of the size of the member, whichever is smaller". However I think this is incorrect; the docs should say that the alignment of a member will be on a boundary that is either a multiple of n or the alignment requirement of the member, whichever is smaller.

The alignment requirement of struct s3 is 2 (due to the #pragma pack(2) in effect when it was declared). So it still gets an alignment of 2 even in the struct that has a #pragma pack(4) in effect. So the layout of struct s4 looks like:

 char c;
 char padding;      // for alignment of the `struct s3`
 char s3.a;
 char s3.padding;   // for alignment
 long s3.b;

Total size == 8.

Comments

0

In s3, char (1) + long (4) = 5 -> 6 (packed)

In s4, char (1) + struct s3 (6) = 7 -> 8 (packed)

I'm not actually sure how #pragma pack works, but this seems reasonable.

Comments

0

This verifies what Michael Burr said:

#include <stdio.h>

#pragma pack(push, 2)
struct s3
{
    long b;
};
#pragma pack(pop)

struct s4
{
    char c;
    struct s3 st3;
};

int main() {
    printf("%lu, %lu\n", sizeof(s3), sizeof(s4));
    return 0;
}

Output: 4, 6

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.