Компиляторы могут и действительно хотят дать объекту больше выравнивания по причинам оптимизации , если только правила ABI для упаковки структуры не вынуждают их смещать его. alignof(double) = 4
для i386 System V, но gcc предпочитает , чтобы придать ему естественное выравнивание, как aligas(sizeof(double)) double x
.
Современный x86 имеет преимущество от 8-байтового выравнивания дляdouble
, но правило alignof(double) == 4
ABI имело смысл еще в 386 дней, когда не было кеша, а fld qword [mem]
действительно выполняло 2 отдельные 32-битные загрузки. Но современное оборудование x86 может выполнять 8-байтовые (или даже 32-байтовые) загрузки за один доступ к кэшу, , если , он не разбит на две строки кэша, что возможно с alignof
Кроме того, выравнивание стека по 16, удешевляющее предоставление локальным 8 или 16-байтовым выравниванием, является более поздней модификацией Linux для i386 System V ABI. До этого каждая функция с локальным double
была бы вынуждена сделать указатель кадра и сделать and $-8, %esp
или что-то в этом роде.
IDK, почему вы думаете, что компилятор будет размещать локальные объекты в их порядкедекларации, как если бы это была структура. Компилятор может свободно собирать большие объекты, поэтому ему не нужно тратить место на отступы.
Посмотрите на вывод asm компилятора, чтобы увидеть, что происходит с его компоновкой стека. И не забудьте включить оптимизацию. Вы можете использовать volatile double
, чтобы остановить оптимизацию адреса памяти.