Подтвердить что ты не робот

Копирует ли байт данных между типами строгого сглаживания?

Предположим, что у меня есть 2 типа A и B с одинаковым размером, и у меня есть две переменные

A a = ... ; // Initialized to some constant of type A
B b;

Если я скопирую содержимое A в B, используя что-то вроде -

assert(sizeof(A) == sizeof(B));
size_t t;
for( t=0; t < sizeof(A); t++){
    ((char*)&b)[t] = ((char*)&a)[t];
}

Означает ли это нарушение строгих правил псевдонимов C? Я знаю, что накладываю указатель на char*, и чтение его не является UB, но меня беспокоят обе причины, связанные с назначением.

Если это не UB, может ли это быть допустимым способом для записи типа?

4b9b3361

Ответ 1

Этот код не нарушает правила псевдонимов. Из последнего проекта (n1570), §6.5 раздела 7:

Объект должен иметь сохраненное значение, доступ к которому имеет только выражение lvalue, которое имеет один из следующие типы:
- тип, совместимый с эффективным типом объекта,
- квалифицированная версия типа, совместимая с эффективным типом объекта,
- тип, который является подписанным или неподписанным типом, соответствующим эффективному типу объект,
- тип, который является подписанным или неподписанным типом, соответствующим квалифицированной версии эффективный тип объекта,
- совокупный или объединенный тип, который включает один из вышеупомянутых типов среди его членов (в том числе, рекурсивно, члена субагрегата или объединенного союза), или
- тип символа

(акцент мой)

Меня беспокоят обе причины, связанные с назначением.

Эти разыменования являются доступными к сохраненному значению с использованием типа символа.

Конечно, вы все равно можете вызвать поведение undefined, если представление вашего A не является допустимым представлением для B.

Ответ 2

В случаях, когда пункт назначения имеет объявленный тип, нет проблем, но в случаях, когда назначение известно только с помощью указателя, стандарт является неоднозначным. Согласно абсолютно ужасно написанному 6.5p6, копируя данные с помощью memcpy или memmove, или "как массив типа символа" [что бы это ни значило] приведет к применению Эффективного типа источника к месту назначения. В стандарте не указывается, что нужно сделать, чтобы скопировать последовательность байтов без операции, рассматриваемой как копирование "массива типа символа".