Проблема здесь не в строгом наложении алиасов, а в требованиях к представлению структуры.
Во-первых, можно использовать псевдоним между char
, signed char
или unsigned char
и любым другим другим типом (в вашем случае unsigned int
. Это позволяет вам написать свой собственный циклы копирования в память, если они определены с использованием типа char
. Это разрешено следующим языком в C99 (§6.5):
6. Эффективным типом объекта для доступа к его сохраненному значению является объявленный тип объекта, если таковой имеется. [Сноска. Выделенные объекты не имеют объявленного типа] [...] Если значение копируется в объект, не имеющий объявленного типа, используя
memcpy или memmove, или копируется как массив символьного типа, затем эффективный тип
измененного объекта для этого доступа и для последующих доступов, которые не изменяют
значение - это эффективный тип объекта, из которого копируется значение, если оно есть. За
при всех других доступах к объекту, не имеющему объявленного типа, эффективный тип объекта
просто тип lvalue, используемого для доступа.
7. Объект должен иметь свое сохраненное значение, доступ к которому осуществляется только через выражение lvalue, имеющее один из следующих типов: [Сноска. Цель этого списка - указать те обстоятельства, при которых объект может или не может иметь псевдоним. ]
- тип, совместимый с эффективным типом объекта,
- [...]
- тип символа.
Подобный язык можно найти в черновике C ++ 0x N3242 §3.11 / 10, хотя не так ясно, когда назначается «динамический тип» объекта (я был бы признателен за любые дальнейшие ссылки на то, что динамический тип массива char, в который был скопирован объект POD в виде массива char с правильным выравниванием).
Таким образом, псевдонимы здесь не проблема. Однако строгое чтение стандарта указывает на то, что реализация C ++ обладает большой свободой при выборе представления unsigned int
.
В качестве одного случайного примера, unsigned int
s может быть 24-разрядным целым числом, представленным в четырех байтах, с перемежением 8 битов заполнения; если какой-либо из этих битов заполнения не соответствует определенному (постоянному) шаблону, он рассматривается как представление прерывания, и разыменование указателя приведет к сбою. Это вероятная реализация? Возможно нет. Но исторически существовали системы с битами четности и другими странностями, и поэтому прямое чтение из сети в unsigned int
, при строгом чтении стандарта не является кошерным.
Теперь, проблема заполнения битов является в основном теоретической проблемой на большинстве систем сегодня, но это стоит отметить. Если вы планируете использовать аппаратное обеспечение ПК, вам не нужно об этом беспокоиться (но не забывайте, что ваши ntohl
s - порядковый номер все еще остается проблемой!)
Структуры, конечно, еще хуже - представления выравнивания зависят от вашей платформы. Я работал над встроенной платформой, в которой все типы имеют выравнивание 1 - никакие отступы когда-либо не вставляются в структуры. Это может привести к несоответствиям при использовании одних и тех же определений структуры на нескольких платформах. Вы можете либо вручную обработать смещения байтов для элементов структуры данных и напрямую ссылаться на них, либо использовать специфическую для компилятора директиву выравнивания для управления заполнением.
Поэтому вы должны быть осторожны при непосредственном приведении из сетевого буфера к собственным типам или структурам. Но псевдонимы в этом случае не проблема.