Данные, которые вы пытаетесь извлечь, пересекают 32-битную границу, поэтому требуются 2 выборки из памяти (но компилятор не обязательно знает об этом во время компиляции).
Примечание. Книга очень старая иречь идет о 32-битных процессорах.Для 64-битной системы вам, возможно, придется изменить int * p = ( int * ) &(u.a[1]);
на int * p = ( int * ) &(u.a[5]);
, чтобы все необходимые данные не могли быть получены за одну выборку памяти с выровненного адреса.
По причинам обратной совместимости большинство процессоров Intel (ипроизводные, такие как AMD), автоматически обрабатывают ошибки выравнивания памяти на уровне команд, поэтому вы не заметите ничего плохого (упрощенно автоматически добавляется дополнительное чтение, блокирующее шину, чтобы убедиться, что между чтениями ничего не меняется).
Вклмногие другие архитектуры ЦП (ARM, PowerPC, MIPS, более новые архитектуры Intel) пример кода вызвал бы проблемы, как описано, но теперь некоторые операционные системы, такие как Linux, могут быть настроены на автоматическое обнаружение ошибки и выполнение «исправления», позволяющегоВ программе для неосознанного возникла проблема.В большинстве программ это, вероятно, останется незамеченным для пользователя, но отнимает много времени и может вызвать реальные проблемы с программным обеспечением и драйверами в реальном времени.
Критический по времени код часто условно компилируется, чтобы выполнять или не выполнять не выровненный доступ согласноархитектура процессора, для которой он компилируется.В linux псевдо-файл "/ proc / cpu / alignment" может использоваться для управления поведением ядра и просмотра статистики о количестве исправлений.