Не совсем понимаю, что происходит при упаковке, например, структур.
Допустим:
#include <stdio.h>
#include <stdlib.h>
struct s
{
int i;
char c;
} __attribute__ ((__packed__));
int main()
{
struct s arr[2];
printf("sizeof(s): %Iu\n", sizeof(struct s));
printf("sizeof(arr): %Iu\n", sizeof(arr));
printf("%p\n", &(arr[1].i));
return 0;
}
Вывод:
sizeof(s): 5
sizeof(arr): 10
0060FEFB
Получается, что начиная arr[1]
поле i
имеет неверное выравнивание, потому что адрес 0060FEFB
не кратен sizeof(int)
. А согласно стандарту, работа с невыровненными данными - это неопределенное поведение. Например, если мы обратимся такому к полю i
через указатель (->
, *
), то получим неопределенное поведение.
Доступ к невыровненым данным формально приводит к неопределенному поведению. Однако С/С++ реализации могут предоставлять такой доступ в качестве расширения. При этом реализации делятся на несколько типов по отношению к выравниванию.
Выравнивание требуется на уровне аппаратуры. Реализация не предпринимает никаких мер для обхода требований аппаратуры. Попытка доступа к невыровненным данным приводит к аварийному завершению программы.
Выравнивание требуется на уровне аппаратуры. Реализация выполняет безопасный (по частям) доступ к потенциально невыровненным данным. Доступ к потенциально невыровненным данным возможен, но существенно менее производителен.
Выравнивание не требуется на уровне аппаратуры. Реализации не надо ни о чем беспокоиться. Доступ к потенциально невыровненным данным возможен, но обычно несколько менее эффективен.
Вы скорее всего имеете дело с реализацией типа 3.
См. также О чём говорит предупреждение о выравнивании данных?
Виртуальный выделенный сервер (VDS) становится отличным выбором
собственно вопрос в шапке: Как задать имя конкретно для кнопки "Show details", с другими кнопками проблем нет
Не получается сохранить токенВ файле preferences