Я бы хотел прояснить следующий момент.
По Стандартам C и C++ разыменование указателя, который содержит адрес с неверным для данного типа выравниванием, - есть неопределенное поведение.
Более того, даже запись в указатель адреса с неверным выравниванием - тоже неопределенное поведение.
Благословенный способ получения данных, чье выравнивание больше единицы (int, float и пр.), из невыровненного расположения, - это использование memcpy(). Этот способ устраняет из кода неопределенное поведение, а вызов функции компилятор заменяет на прямое помещение в регистр, если это возможно.
Я не понял одного - каков безопасный способ получить величину смещения для заданного поля?
Мне известно про существование offsetof(). И этот способ гарантированно был бы безопасен, если бы это была buildin функция, но в моем компиляторе это не так.
Как видно из кода, этот макрос содержит разыменование нулевого указателя. Как компилятор это учитывает и учитывает ли? Или это костыль, на надежность которого полагаться не стоит?
Я не понял одного - каков безопасный способ получить величину смещения для заданного поля?
Возьмите готовый объект данного типа и вычисляйте на здоровье. При наличии готового объекта, вам не придется заниматься работой с невалидными указателями. Это неудобно, но формально является безопасным способом.
Как видно из кода, этот макрос содержит разыменование нулевого указателя.
Реализация offsetof находится внутри реализации стандартной библиотеки. Правила языков С и С++ на эту территории не распространяются. Это вообще не С и не С++. Разглядывать реализацию offsetof с точки зрения требований C++ - бессмысленное занятие.
Сборка персонального компьютера от Artline: умный выбор для современных пользователей