liveBook · Manning

Alignment

As explained in Modern C

Alignment is the requirement that an object be stored at an address suitable for its type's access constraints.

A misaligned cast

A byte buffer is cast to complex double* at several offsets. Access works at offsets 16 and 8, but offset 4 produces a bus error: the address does not satisfy complex double's alignment requirement. section 12.7

 1   #include <stdio.h>
 2   #include <inttypes.h>
 3   #include <complex.h>
 4   #include "crash.h"
 5
 6   void enable_alignment_check(void);
 7   typedef complex double cdbl;
 8
 9   int main(void) {
10     enable_alignment_check();
11     /* An overlay of complex values and bytes. */
12     union {
13       cdbl val[2];
14       unsigned char buf[sizeof(cdbl[2])];
15     } toocomplex = {
16       .val = { 0.5 + 0.5*I, 0.75 + 0.75*I, },
17     };
18     printf("size/alignment: %zu/%zu\n",
19            sizeof(cdbl), _Alignof(cdbl));
20     /* Run over all offsets, and crash on misalignment. */
21     for (size_t offset = sizeof(cdbl); offset; offset /=2) {
22       printf("offset\t%zu:\t", offset);
23       fflush(stdout);
24       cdbl* bp = (cdbl*)(&toocomplex.buf[offset]); // align!
25       printf("%g\t+%gI\t", creal(*bp), cimag(*bp));
26       fflush(stdout);
27       *bp *= *bp;
28       printf("%g\t+%gI", creal(*bp), cimag(*bp));
29       fputc('\n', stdout);
30     }
31   }


!@%STYLE%@!
{"css":"{\"css\": \"font-weight: bold;\"}","target":"[[{\"line\":0,\"ch\":1},{\"line\":0,\"ch\":2}],[{\"line\":9,\"ch\":0},{\"line\":9,\"ch\":1}],[{\"line\":10,\"ch\":0},{\"line\":10,\"ch\":1}],[{\"line\":11,\"ch\":0},{\"line\":11,\"ch\":1}],[{\"line\":12,\"ch\":0},{\"line\":12,\"ch\":1}],[{\"line\":13,\"ch\":0},{\"line\":13,\"ch\":1}],[{\"line\":14,\"ch\":0},{\"line\":14,\"ch\":1}],[{\"line\":15,\"ch\":0},{\"line\":15,\"ch\":1}],[{\"line\":16,\"ch\":0},{\"line\":16,\"ch\":1}],[{\"line\":17,\"ch\":0},{\"line\":17,\"ch\":1}],[{\"line\":18,\"ch\":0},{\"line\":18,\"ch\":1}],[{\"line\":20,\"ch\":1},{\"line\":20,\"ch\":2}],[{\"line\":30,\"ch\":1},{\"line\":30,\"ch\":2}],[{\"line\":0,\"ch\":5},{\"line\":0,\"ch\":13}],[{\"line\":1,\"ch\":5},{\"line\":1,\"ch\":13}],[{\"line\":2,\"ch\":5},{\"line\":2,\"ch\":13}],[{\"line\":3,\"ch\":5},{\"line\":3,\"ch\":13}],[{\"line\":1,\"ch\":1},{\"line\":1,\"ch\":2}],[{\"line\":11,\"ch\":1},{\"line\":11,\"ch\":2}],[{\"line\":12,\"ch\":18},{\"line\":12,\"ch\":19}],[{\"line\":13,\"ch\":39},{\"line\":13,\"ch\":40}],[{\"line\":19,\"ch\":0},{\"line\":19,\"ch\":1}],[{\"line\":20,\"ch\":0},{\"line\":20,\"ch\":1}],[{\"line\":21,\"ch\":0},{\"line\":21,\"ch\":1}],[{\"line\":22,\"ch\":0},{\"line\":22,\"ch\":1}],[{\"line\":23,\"ch\":0},{\"line\":23,\"ch\":1}],[{\"line\":24,\"ch\":0},{\"line\":24,\"ch\":1}],[{\"line\":25,\"ch\":0},{\"line\":25,\"ch\":1}],[{\"line\":26,\"ch\":0},{\"line\":26,\"ch\":1}],[{\"line\":27,\"ch\":0},{\"line\":27,\"ch\":1}],[{\"line\":28,\"ch\":0},{\"line\":28,\"ch\":1}],[{\"line\":0,\"ch\":5},{\"line\":0,\"ch\":13}],[{\"line\":1,\"ch\":5},{\"line\":1,\"ch\":13}],[{\"line\":2,\"ch\":5},{\"line\":2,\"ch\":13}],[{\"line\":3,\"ch\":5},{\"line\":3,\"ch\":13}],[{\"line\":2,\"ch\":1},{\"line\":2,\"ch\":2}],[{\"line\":12,\"ch\":1},{\"line\":12,\"ch\":2}],[{\"line\":22,\"ch\":1},{\"line\":22,\"ch\":2}],[{\"line\":29,\"ch\":0},{\"line\":29,\"ch\":1}],[{\"line\":30,\"ch\":0},{\"line\":30,\"ch\":1}],[{\"line\":0,\"ch\":5},{\"line\":0,\"ch\":13}],[{\"line\":1,\"ch\":5},{\"line\":1,\"ch\":13}],[{\"line\":2,\"ch\":5},{\"line\":2,\"ch\":13}],[{\"line\":3,\"ch\":5},{\"line\":3,\"ch\":13}],[{\"line\":2,\"ch\":15},{\"line\":2,\"ch\":24}],[{\"line\":3,\"ch\":1},{\"line\":3,\"ch\":2}],[{\"line\":13,\"ch\":1},{\"line\":13,\"ch\":2}],[{\"line\":23,\"ch\":1},{\"line\":23,\"ch\":2}],[{\"line\":0,\"ch\":5},{\"line\":0,\"ch\":13}],[{\"line\":1,\"ch\":5},{\"line\":1,\"ch\":13}],[{\"line\":2,\"ch\":5},{\"line\":2,\"ch\":13}],[{\"line\":3,\"ch\":5},{\"line\":3,\"ch\":13}],[{\"line\":4,\"ch\":1},{\"line\":4,\"ch\":2}],[{\"line\":14,\"ch\":1},{\"line\":14,\"ch\":2}],[{\"line\":15,\"ch\":20},{\"line\":15,\"ch\":21}],[{\"line\":24,\"ch\":1},{\"line\":24,\"ch\":2}],[{\"line\":5,\"ch\":1},{\"line\":5,\"ch\":2}],[{\"line\":15,\"ch\":1},{\"line\":15,\"ch\":2}],[{\"line\":25,\"ch\":1},{\"line\":25,\"ch\":2}],[{\"line\":5,\"ch\":5},{\"line\":5,\"ch\":9}],[{\"line\":8,\"ch\":14},{\"line\":8,\"ch\":18}],[{\"line\":5,\"ch\":5},{\"line\":5,\"ch\":9}],[{\"line\":8,\"ch\":14},{\"line\":8,\"ch\":18}],[{\"line\":6,\"ch\":1},{\"line\":6,\"ch\":2}],[{\"line\":15,\"ch\":33},{\"line\":15,\"ch\":34}],[{\"line\":16,\"ch\":1},{\"line\":16,\"ch\":2}],[{\"line\":26,\"ch\":1},{\"line\":26,\"ch\":2}],[{\"line\":6,\"ch\":5},{\"line\":6,\"ch\":12}],[{\"line\":2,\"ch\":15},{\"line\":2,\"ch\":22}],[{\"line\":6,\"ch\":13},{\"line\":6,\"ch\":20}],[{\"line\":10,\"ch\":24},{\"line\":10,\"ch\":31}],[{\"line\":14,\"ch\":12},{\"line\":14,\"ch\":19}],[{\"line\":23,\"ch\":32},{\"line\":23,\"ch\":39}],[{\"line\":6,\"ch\":21},{\"line\":6,\"ch\":27}],[{\"line\":7,\"ch\":1},{\"line\":7,\"ch\":2}],[{\"line\":17,\"ch\":1},{\"line\":17,\"ch\":2}],[{\"line\":27,\"ch\":1},{\"line\":27,\"ch\":2}],[{\"line\":8,\"ch\":1},{\"line\":8,\"ch\":2}],[{\"line\":18,\"ch\":1},{\"line\":18,\"ch\":2}],[{\"line\":28,\"ch\":1},{\"line\":28,\"ch\":2}],[{\"line\":1,\"ch\":15},{\"line\":1,\"ch\":18}],[{\"line\":8,\"ch\":5},{\"line\":8,\"ch\":8}],[{\"line\":17,\"ch\":9},{\"line\":17,\"ch\":12}],[{\"line\":21,\"ch\":11},{\"line\":21,\"ch\":14}],[{\"line\":24,\"ch\":11},{\"line\":24,\"ch\":14}],[{\"line\":27,\"ch\":11},{\"line\":27,\"ch\":14}],[{\"line\":8,\"ch\":9},{\"line\":8,\"ch\":13}],[{\"line\":5,\"ch\":5},{\"line\":5,\"ch\":9}],[{\"line\":8,\"ch\":14},{\"line\":8,\"ch\":18}],[{\"line\":9,\"ch\":0},{\"line\":9,\"ch\":2}],[{\"line\":10,\"ch\":0},{\"line\":10,\"ch\":2}],[{\"line\":11,\"ch\":0},{\"line\":11,\"ch\":2}],[{\"line\":11,\"ch\":7},{\"line\":11,\"ch\":12}],[{\"line\":12,\"ch\":0},{\"line\":12,\"ch\":2}],[{\"line\":13,\"ch\":0},{\"line\":13,\"ch\":2}],[{\"line\":13,\"ch\":9},{\"line\":13,\"ch\":22}],[{\"line\":13,\"ch\":27},{\"line\":13,\"ch\":33}],[{\"line\":18,\"ch\":14},{\"line\":18,\"ch\":20}],[{\"line\":20,\"ch\":28},{\"line\":20,\"ch\":34}],[{\"line\":14,\"ch\":0},{\"line\":14,\"ch\":2}],[{\"line\":15,\"ch\":0},{\"line\":15,\"ch\":2}],[{\"line\":16,\"ch\":0},{\"line\":16,\"ch\":2}],[{\"line\":17,\"ch\":0},{\"line\":17,\"ch\":2}],[{\"line\":17,\"ch\":7},{\"line\":17,\"ch\":13}],[{\"line\":21,\"ch\":9},{\"line\":21,\"ch\":15}],[{\"line\":24,\"ch\":9},{\"line\":24,\"ch\":15}],[{\"line\":27,\"ch\":9},{\"line\":27,\"ch\":15}],[{\"line\":18,\"ch\":0},{\"line\":18,\"ch\":2}],[{\"line\":13,\"ch\":27},{\"line\":13,\"ch\":33}],[{\"line\":18,\"ch\":14},{\"line\":18,\"ch\":20}],[{\"line\":20,\"ch\":28},{\"line\":20,\"ch\":34}],[{\"line\":18,\"ch\":28},{\"line\":18,\"ch\":36}],[{\"line\":19,\"ch\":0},{\"line\":19,\"ch\":2}],[{\"line\":20,\"ch\":0},{\"line\":20,\"ch\":2}],[{\"line\":20,\"ch\":7},{\"line\":20,\"ch\":10}],[{\"line\":20,\"ch\":12},{\"line\":20,\"ch\":18}],[{\"line\":13,\"ch\":27},{\"line\":13,\"ch\":33}],[{\"line\":18,\"ch\":14},{\"line\":18,\"ch\":20}],[{\"line\":20,\"ch\":28},{\"line\":20,\"ch\":34}],[{\"line\":21,\"ch\":0},{\"line\":21,\"ch\":2}],[{\"line\":17,\"ch\":7},{\"line\":17,\"ch\":13}],[{\"line\":21,\"ch\":9},{\"line\":21,\"ch\":15}],[{\"line\":24,\"ch\":9},{\"line\":24,\"ch\":15}],[{\"line\":27,\"ch\":9},{\"line\":27,\"ch\":15}],[{\"line\":22,\"ch\":0},{\"line\":22,\"ch\":2}],[{\"line\":22,\"ch\":9},{\"line\":22,\"ch\":15}],[{\"line\":25,\"ch\":9},{\"line\":25,\"ch\":15}],[{\"line\":22,\"ch\":16},{\"line\":22,\"ch\":22}],[{\"line\":25,\"ch\":16},{\"line\":25,\"ch\":22}],[{\"line\":28,\"ch\":21},{\"line\":28,\"ch\":27}],[{\"line\":23,\"ch\":0},{\"line\":23,\"ch\":2}],[{\"line\":24,\"ch\":0},{\"line\":24,\"ch\":2}],[{\"line\":17,\"ch\":7},{\"line\":17,\"ch\":13}],[{\"line\":21,\"ch\":9},{\"line\":21,\"ch\":15}],[{\"line\":24,\"ch\":9},{\"line\":24,\"ch\":15}],[{\"line\":27,\"ch\":9},{\"line\":27,\"ch\":15}],[{\"line\":24,\"ch\":30},{\"line\":24,\"ch\":35}],[{\"line\":27,\"ch\":28},{\"line\":27,\"ch\":33}],[{\"line\":24,\"ch\":42},{\"line\":24,\"ch\":47}],[{\"line\":27,\"ch\":40},{\"line\":27,\"ch\":45}],[{\"line\":25,\"ch\":0},{\"line\":25,\"ch\":2}],[{\"line\":22,\"ch\":9},{\"line\":22,\"ch\":15}],[{\"line\":25,\"ch\":9},{\"line\":25,\"ch\":15}],[{\"line\":22,\"ch\":16},{\"line\":22,\"ch\":22}],[{\"line\":25,\"ch\":16},{\"line\":25,\"ch\":22}],[{\"line\":28,\"ch\":21},{\"line\":28,\"ch\":27}],[{\"line\":26,\"ch\":0},{\"line\":26,\"ch\":2}],[{\"line\":27,\"ch\":0},{\"line\":27,\"ch\":2}],[{\"line\":17,\"ch\":7},{\"line\":17,\"ch\":13}],[{\"line\":21,\"ch\":9},{\"line\":21,\"ch\":15}],[{\"line\":24,\"ch\":9},{\"line\":24,\"ch\":15}],[{\"line\":27,\"ch\":9},{\"line\":27,\"ch\":15}],[{\"line\":24,\"ch\":30},{\"line\":24,\"ch\":35}],[{\"line\":27,\"ch\":28},{\"line\":27,\"ch\":33}],[{\"line\":24,\"ch\":42},{\"line\":24,\"ch\":47}],[{\"line\":27,\"ch\":40},{\"line\":27,\"ch\":45}],[{\"line\":28,\"ch\":0},{\"line\":28,\"ch\":2}],[{\"line\":28,\"ch\":9},{\"line\":28,\"ch\":14}],[{\"line\":22,\"ch\":16},{\"line\":22,\"ch\":22}],[{\"line\":25,\"ch\":16},{\"line\":25,\"ch\":22}],[{\"line\":28,\"ch\":21},{\"line\":28,\"ch\":27}],[{\"line\":29,\"ch\":0},{\"line\":29,\"ch\":2}],[{\"line\":30,\"ch\":0},{\"line\":30,\"ch\":2}]]"}
!@%STYLE%@!

Inspect the complete program that overlays complex values with bytes, prints size and alignment, and tests progressively smaller offsets. section 12.7

Alignment is the set of byte positions at which an object of a type may start. Most non-character types cannot begin at an arbitrary byte position; they commonly require a word boundary. Casting a character pointer to an object pointer is therefore unsafe when the resulting address is misaligned. section 12.7

TAKEAWAY

  • Different architectures tolerate misalignment differently; code that appears to work on i386 can fail elsewhere. section 12.7
  • Not every unsigned-char array can safely represent an object of every other type. section 12.8
  • The alignas declaration specifier can request stronger alignment for objects such as complex double, float arrays, or unsigned-char arrays. section 12.7

How Modern C covers it

How deep it goes
Defines permissible starting positions, demonstrates a crashing misaligned access, and stops short of broader hardware implementation details.
Examples
Demonstrates a complex double and byte-buffer union tested at offsets 16, 8, 4, 2, and 1.
What it assumes
Assumes pointers, casts, unions, and object representations while defining alignment through a concrete failure.
What you can do after
Diagnose misaligned pointer access and request suitable storage alignment with alignas.
How it connects
Connects pointer conversions, object representation, unions, character arrays, and effective types.

Also explained in

Compare how 2 books explain alignment →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Modern C. The section links point to the parts of the book it draws on.