Для x86-64 System V, alignof(maxalign_t) == 16
, поэтому malloc
всегда возвращает 16-байтовые выровненные указатели.Похоже, ваш распределитель не работает и будет нарушать ABI, если используется также для long double
.(Повторно отправив это как ответ, поскольку выясняется, что было ответом.)
Память, возвращаемая malloc
, гарантированно может содержать любой стандартный тип, что означает выравниваниедостаточно, если размер достаточно велик.
Это не может быть 32-битный код, потому что gcc не поддерживает __int128
в 32-битных целях.(32-битный glibc malloc
гарантирует только 8-байтовое выравнивание.)
В общем, компилятору разрешается создавать код, который дает сбой, если вы нарушаете требования к выравниванию типов.На x86 все обычно работает с не выровненной памятью, пока компилятор не использует необходимые SIMD инструкции для выравнивания.Даже автоматическая векторизация с неправильным выравниванием uint16_t*
может привести к сбою ( Почему невыровненный доступ к памяти mmap иногда вызывает ошибку по умолчанию на AMD64? ), поэтому не думайте, что узкие типы всегда безопасны.Используйте memcpy
, если вам нужно выразить невыровненную нагрузку в C.
Очевидно, alignof(__int128)
равно 16. Таким образом, они не повторяют странности из i386 System V, где даже 8-байтовые объекты являютсяТолько гарантированное 4-байтовое выравнивание и правила упаковки структуры означают, что компиляторы не могут дать им естественное выравнивание.
Это хорошо, потому что это делает его эффективным для копирования с SSE, а значит _Atomic __int128
не требуется никакой дополнительной специальной обработки, чтобы избежать разбиения строки кэша, что делает lock cmpxchg16b
очень медленным.