Hongyuan
Hongyuan

Reputation: 102

In the sample, why size of `char _Alignas(double)` is not 8?

#include <stdio.h>
int main(void)
{
    char c1 = '0';
    char _Alignas(double) c2 = '0';

    printf("char alignment:   %zd\n", _Alignof(char));
    printf("double alignment: %zd\n", _Alignof(double));
    printf("&c1: %p\n", &c1);
    printf("&c2: %p\n", &c2);

    return 0;
}

Run in my environment, result is:

char alignment: 1
double alignment: 8
&c1: 000000000061FE1F
&c2: 000000000061FE18

Compiled by gcc version 8.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project).

I wonder why the number of bytes between &c2 and &c1 is 7, not 8 (sizeof(double) in my environment)?

Upvotes: 0

Views: 105

Answers (2)

Geoduck
Geoduck

Reputation: 9005

Alignment determines where the addresses will be, not how much space they will take.

A char only takes up 1 byte, even if it is aligned on an 8 byte boundary. There are 6 unused bytes between c1 and c2.

Often, the alignment and the size will be the same, or the alignment is rounded up to a power of 2. That's because on many architectures it may require multiple FETCH instructions to retrieve from a non-aligned memory address.

In your case, c1 is aligned on a 1-byte boundary, so it is placed at the first available position on the stack.

c2 is aligned on an 8-byte boundary, so it skips over however many bytes are needed until the address is aligned on an 8 byte boundary. This means (address % 8) == 0. If c2 were of type double, it would need to move to the next aligned address, 8 more bytes ahead, but since it is only a char it fits just fine at the first 8-byte boundary. (EDIT: as others have pointed out, the compiler could rearrange the variables, and probably would in that case)

The alignment can be greater or less than the size of the element.

On some architecture, you simply HAD to align on 2 or 4 byte boundaries. The computers simply could not address the "in between bytes". The address lines aren't needed, so you can address 2^16 bytes of memory using only 14 address lines if you align on 4 byte addresses (and always read 4 bytes). That can reduce the size needed for the memory bus.

Upvotes: 1

phuclv
phuclv

Reputation: 41794

why char _Alignas double size is not 8?

Alignment means the address is a multiple of some value. It has nothing to do with the size of a variable. _Alignas(8) means the address will be a multiple of 8, i.e. ending with 0 or 8 in hexadecimal

I wonder why the bytes between &c2 and &c1 is 7, not 8 (sizeof double in my environment)?

The positions of variables on stack isn't specified. The compiler can freely put c1 before or after c2. The only requirement here is the alignment of c2 which must be a multiple of 8. If c1 is at a multiple of 8 and the compiler chooses to put c2 right after that then 7 bytes of padding will be used. But they can obviously put c1 right before c2 and their addresses will differ by only 1. You can easily see each compiler puts the variables in different positions with different distances

For more details read

Upvotes: 2

Related Questions