Why is the double element in the structure not aligned on an 8-byte boundary?

This is about memory alignment. In the code below, I expected the offset b inside the structure to be 8 (32-bit machine). See here . There, when b always occurs in the cache line. However, it is not. The b element in the global struct test1 object seems aligned. I am not sure if this is accidental or the compiler does it intentionally.

I wanted to understand why the compiler does not fill 4 bytes after a .

 struct test1 { int a; double b; }t1; int main() { struct test1 *p = malloc(sizeof(struct test1)); printf("sizes int %d, float %d, double %d, long double %d\n", sizeof(int), sizeof(float), sizeof(double), sizeof(long double)); printf("offset of b %d\n",(int)&(t1.b)-(int)&(t1)); printf("\naddress of b (on heap) = %p, addr of b (on data seg) = %p\n",&(p->b), &(t1.b)); return 0; } 

Output...

 sizes int 4, float 4, double 8, long double 12 offset of b 4 address of b (on heap) = 0x804a07c, addr of b (on data seg) = 0x80497e0 

I am using the standard gcc compiler on ubuntu 10.04

+5
source share
3 answers

According to System V ABI for i386 , page 28, double receives only 4 bytes, but compilers recommend providing an option for 8 bytes. This seems to be what GCC has implemented on Linux, with this option called -malign-double .

Another alternative is to use -m64 to get the x86-64 object code, which is the default for some systems, including Mac OS X.

+5
source

I expected the offset b inside the structure to be 8 (32-bit machine). See here

Your links explain why this might be beneficial for an 8-align double. This does not mean that doubling will always be 8-aligned. If your sources claim that they are always 8-aligned, and you observe an implementation in which they are not, then your sources are wrong.

From the GCC man page:

Aligning β€œdouble” variables at the two-word boundary will generate code that runs slightly faster on the Pentium due to more memory.

Thus, the GCC stated that the reason for 4-alignment is memory preservation. You can use -malign-double and -mno-align-double to control this, although of course you run the risk of creating binary incompatibilities if you split the structures between code compiled with conflicting parameters. For certain objects / structure elements, you can use GCC __attribute__((aligned)) , _Alignas (in C11) or alignas (in C ++ 11), all of which can take an integer constant to indicate the desired alignment.

+4
source

ANSI C has no guarantee of alignment.

Alignment occurs with automatic variables more than with anything declared on the heap. If you are on POSIX, use memalign (3) to get the memory that you are sure is aligned. Malloc can return memory at any offset. You can use compiler directives such as __attribute__ ((__packed__)) to place your own alignments.

0
source

Source: https://habr.com/ru/post/985929/


All Articles