Skip to content

Fix padding size comment in struct S3 - #5963

Closed
Sniff (darkclif) wants to merge 1 commit into
MicrosoftDocs:mainfrom
darkclif:patch-1
Closed

Sniff (darkclif) wants to merge 1 commit into
MicrosoftDocs:mainfrom
darkclif:patch-1

Conversation

@darkclif

Copy link
Copy Markdown

Updated the comment to reflect the correct padding size for struct S3.

Updated the comment to reflect the correct padding size for struct S3.
@prmerger-automator

Copy link
Copy Markdown
Contributor

Sniff (@darkclif) : Thanks for your contribution! The author(s) and reviewer(s) have been notified to review your proposed change.

@prmerger-automator

Copy link
Copy Markdown
Contributor

Sniff (@darkclif) : Thanks for your contribution! The author(s) and reviewer(s) have been notified to review your proposed change.

@learn-build-service-prod

Copy link
Copy Markdown
Contributor

Learn Build status updates of commit a4cd024:

✅ Validation status: passed

File Status Preview URL Details
docs/cpp/align-cpp.md ✅Succeeded

For more details, please refer to the build report.

@v-regandowner

Copy link
Copy Markdown
Contributor

Tyler Whitney (@TylerMSFT)

Can you review the proposed changes?

IMPORTANT: When the changes are ready for publication, adding a #sign-off comment is the best way to signal that the PR is ready for the review team to merge.

#label:"aq-pr-triaged"
@MicrosoftDocs/public-repo-pr-review-team

@prmerger-automator prmerger-automator Bot added the aq-pr-triaged Tracking label for the PR review team label Sep 7, 2026

@TylerMSFT Tyler Whitney (TylerMSFT) left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for catching this.

@TylerMSFT

Tyler Whitney (TylerMSFT) commented Sep 10, 2026

Copy link
Copy Markdown
Collaborator

Actually, I think I just made the same mistake you may have made.
There's 16 bytes of padding for S1.
S3 embeds S1 using bytes 0–31
S3::a uses bytes 32–35.
Because S3 inherits the 32-byte alignment requirement, its size rounds from 36 (4 bigger than 32) to 64, producing 28 bytes of trailing padding.

S1 contains four int members. Each occupies 4 bytes, for 16 bytes of member storage:
S1 member storage: 4 ints x 4 bytes = 16 bytes
S1 is explicitly declared with 32-byte alignment. So its total object size must be a multiple of 32 bytes. The compiler adds 16 bytes of padding: S1: [ four ints: 16 bytes ][ padding: 16 bytes ] = 32 bytes

Those 16 padding bytes are part of S1

Layout of S3

S3 contains an S1, followed by its own int a member:

bytes 0-31: S3::s1 (the complete 32-byte S1 object)
bytes 32-35: S3::a
bytes 36-63: trailing padding in S3


Because `S3` contains `S1`, `S3` also has a 32-byte alignment requirement. But its members occupy 36 bytes in total:

`S3::s1`: 32 bytes
`S3::a`:   4 bytes
-----------------
Total:  36 bytes

The next size that is a multiple of 32 is 64 bytes. So, S3 trailing padding = 64 - 36 = 28 bytes

The compiler rounds an object's size to a multiple of its alignment so that if it declared as an array, every element will be correctly aligned. For example, because sizeof(S3) is 64, each element in an S3 array begins at a 32-byte boundary:

S3 array element 0 starts at offset 0
S3 array element 1 starts at offset 64
S3 array element 2 starts at offset 128.

Here's a little test app you can try:

#include <iostream>
#include <cstddef>

#define CACHE_LINE  32
#define CACHE_ALIGN __declspec(align(CACHE_LINE))

struct CACHE_ALIGN S1 { // cache align all instances of S1
    int a, b, c, d;
};

static_assert(alignof(S1) == CACHE_LINE, "S1 must be 32-byte aligned");
static_assert(sizeof(S1) == CACHE_LINE, "S1 must occupy 32 bytes");
static_assert(sizeof(S1) - sizeof(int) * 4 == 16, "S1 must have 16 bytes of trailing padding");

struct S1 s1;   // s1 is 32-byte cache aligned

__declspec(align(8)) struct S2 {
    int a, b, c, d;
};

struct S3 {
    struct S1 s1;   // S3 inherits cache alignment requirement from S1
    int a;         // a is now cache aligned because of s1
    // 28 bytes of trailing padding
};

static_assert(alignof(S3) == CACHE_LINE, "S3 must inherit S1's 32-byte alignment");
static_assert(offsetof(S3, a) == sizeof(S1), "S3::a must follow S1 at offset 32");
static_assert(sizeof(S3) == 64, "S3 must occupy 64 bytes");
static_assert(sizeof(S3) - offsetof(S3, a) - sizeof(S3::a) == 28, "S3 must have 28 bytes of trailing padding");

int main()
{
    std::cout << sizeof(S3);
    return 0;
}

Closing this PR since the original value (28) is correct.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants