Modern C (C11/C17/C23)

alignas and alignof

/ a-LINE-az, a-LINE-of /

Hardware does not place data wherever it pleases: a 4-byte int usually wants to sit at an address that is a multiple of 4, an 8-byte double at a multiple of 8. That requirement is called alignment, and the address being a multiple of N means it is N-aligned. Most of the time the compiler arranges this for you, but sometimes you need to ASK what a type's alignment is, or DEMAND a stronger alignment than usual.

alignof(T) is a compile-time operator that yields the alignment requirement of type T as a size_t (for example alignof(double) is often 8). alignas(N) is a specifier you attach to a declaration to force at least N-byte alignment, where N is a power of two — for instance alignas(64) double buf[8] places buf at a 64-byte boundary. The underscore spellings _Alignof and _Alignas are the C11 keywords; the unprefixed alignof and alignas are macros from <stdalign.h> in C11 and become real keywords in C23. Asking for a SMALLER alignment than the type naturally needs is not allowed.

They matter for performance and correctness: aligning a frequently used buffer to a 64-byte cache line can avoid false sharing between threads, and some SIMD and DMA hardware require specific alignment or they fault. A common misconception: alignment is about the ADDRESS, not the size — a type can be 12 bytes but require 4-byte alignment, and padding inside a struct exists precisely to keep each member properly aligned.

#include <stdalign.h> alignas(64) double buf[8]; // start buf on a 64-byte (cache-line) boundary size_t a = alignof(double); // typically 8 // (uintptr_t)buf % 64 == 0

alignof reads a type's natural alignment; alignas raises a declaration's alignment to a chosen power of two.

Alignment is about the address being a multiple of N, not about size; you may strengthen alignment with alignas but never weaken a type below its natural requirement.

Also called
_Alignas_Alignofalignment specifier對齊指定子