Home > Back-end >  when alignof operator used in struct does it affect sizeof
when alignof operator used in struct does it affect sizeof

Time:12-16

struct s11
{
    alignas(16) char s;
    int i;
};
  1. does alignas(n) X x mean it would allocate n bytes to hold a X, when X is actually much smaller than n bytes, the rest memory would be all 0s?

  2. when s11.s is in memory 0x0, does that mean s11.i would be at 0x10? However, the following pdiff is 0x4

s11 o;
ptrdiff_t pdiff = (char*)&o.i - (char*)&o.s;
  1. Please explain why sizeof(s11) is not 16 times 2, while sizeof(s1) is 8 times 3?
struct s1
{
    char s;
    double d; // alignof(double) is 8. 
    int i;
}

EDIT: This is what I found after a lot of digging and code snippets, that how alignas affect struct(class) size.

alignas(n) X x means in memory x is located at a place with an offset of multiple of n bytes, starts from 0x00. Therefore, s11.s can be located at 0x00, 0x10, 0x20 and so on. Because s11.s is the first field, it is at 0x00, and it is a char, so it ocupies 1 bytes.

So is the 2nd field. int has an align 4, therefore it can be located at 0x00, 0x04, 0x08, 0x0c, etc. Because the first byte is taken by s11.s, so s11.i is located at 0x04.

CodePudding user response:

when alignof operator used in struct does it affect sizeof

You aren't using alignof operator. You're using alignas specifier.

Using alignas specifier doesn't necessarily affect the size of a class, but it can affect it.

  1. does alignas(n) X x mean it would allocate n bytes to hold a X, when X is actually much smaller than n bytes, the rest memory would be all 0s?

No. If there is padding, there's no guarantee that it would be all 0s. Furthermore, there are cases where the memory can be occupied by other members.

  1. when s11.s is in memory 0x0, does that mean s11.i would be at 0x10?

No.

  1. Please explain why sizeof(s11) is not 16 times 2

Probably because it doesn't need to be. Here is an example layout that would satisfy the alignment requirements:

offset  member   alignment  offset % alignment must equal 0
0       s        16         0 % 16 == 0
1       padding
2       padding
3       padding
4       i        4          4 % 4 == 0
5       i
6       i
7       i
8       padding
9       padding
10      padding
11      padding
12      padding
13      padding
14      padding
15      padding
---
super alignment  16         16 % 16 == 0

while sizeof(s1) is 8 times 3?

Here is an example layout that would satisfy the alignment requirements:

offset  member   alignment  offset % alignment must equal 0
0       s        1          0 % 1 == 0
1       padding
2       padding
3       padding
4       padding
5       padding
6       padding
7       padding
8       d        8          8 % 8 == 0
9       d
10      d
11      d
12      d
13      d
14      d
15      d
16      i        4          16 % 4 == 0
17      i
18      i
19      i
20      padding
21      padding
22      padding
23      padding
---
super alignment  8          24 % 8 == 0

My examples apply to a system where double is 8 bytes and int is 4.

CodePudding user response:

  1. No, it means the starting address of the member s must be aligned on a 16-byte boundary. Probably in the case of it being the first member of a struct, this will result in the struct itself adopting that alignment and not affecting the size.

  2. No, there is no specified alignment pertaining to the member i, so normal alignment rules apply. If you're getting 4 then your system is using integers that have a size of 4 bytes, and are similarly aligned. The value of padding bytes is unspecified.

  3. The first explanation is in my answer to #2. Follow-up incorporting the answer to #1, the size will probably be 16 due to the required structure alignment. And sizeof(s1) is 8 times 3 because of the alignment requirements of the double member causing padding elsewhere, combined with the entire structure's alignment. Moving the char member to the end of the structure will reduce the total size.

  •  Tags:  
  • c
  • Related