Reputation: 102
#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
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
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