Double stack alignment question using gcc compiler for x86 architecture
Asked Answered
T

1

0

Doubt about data type alignment, I'm learning about alignment now, and I have some questions, so I know double aligns to 4 bytes in linux when compiled with gcc for i386 architecture and so the address of a double has which is aligned to a multiple of 4, but it doesn't happen when I'm using the stack, only when I use data structure

#include <stdio.h>

int main(void) {

    double x = 5; //     8 
    char s = 'a'; //    +1
    double y = 2; //   ---- = 9 + 8 = 17 + alignment = 20 

    //int x = 5; //     4
    //char s = 'a';    +1
    //int y = 2;     --------= 5 + 4 = 9 + alignment = 12 

    size_t a, b;
    a = (size_t)&s;
    b = (size_t)&y;

    printf("%zu", a - b); // it wasn't supposed to be 11 instead of 15
    return 0;
}

Compile: $ gcc -m32 -o align align.c

Ternion answered 15/10, 2019 at 4:22 Comment(1)
Related but not a duplicate: Why double in C is 8 bytes aligned? seems to be asking why x86-64 has alignof(double) == 8.Kulseth
K
5

Compilers can and do choose to give an object more alignment for optimization reasons, unless ABI's struct-packing rules force them to misalign it. alignof(double) = 4 for i386 System V, but gcc prefers to give it natural alignment, like aligas(sizeof(double)) double x.

Modern x86 does benefit from 8-byte alignment for double, but the alignof(double) == 4 ABI rule made sense back in 386 days when there wasn't cache, and fld qword [mem] did take 2 separate 32-bit loads. But modern x86 hardware can do 8-byte (or even 32-byte) loads in a single access to cache, if it isn't split across two cache lines, which is possible with alignof < sizeof.

Also, aligning the stack by 16 making it cheap to give locals 8 or 16-byte alignment is a more recent Linux modification to the i386 System V ABI. Before that, every function with a double local would have been forced to make a frame pointer and do and $-8, %esp or something.


IDK why you think the compiler would lay out locals in their order of declaration, as if it were a struct. The compiler is free to put the large objects together so it doesn't have to waste space on padding.

Look at compiler asm output to see what's going on with its stack layout. And don't forget to enable optimization. You might use volatile double to stop its memory address from optimizing away.

Kulseth answered 15/10, 2019 at 4:32 Comment(3)
Is it 4-byte aligned?Perrins
@AnttiHaapala: yes, i386 System V has alignof(double) == 4. This is not really a duplicate. The OP's code isn't super helpful but yes this is real.Kulseth
Grateful, I'll do what you told me, I'll disassemble to understand betterTernion

© 2022 - 2024 — McMap. All rights reserved.