Разрешено ли приведение из TYPE* в unsigned char*?

C99 - в частности, раздел 6.2.6.1, параграф 4 - гласит, что копирование представления объекта в массив беззнаковых символов допускается:

struct {
    int foo;
    double bar;
} baz;
unsigned char bytes[sizeof baz];

// Do things with the baz structure.

memcpy(bytes, &baz, sizeof bytes);

// Do things with the bytes array.

Мой вопрос: не можем ли мы избежать дополнительного выделения памяти и операции копирования простым приведением? Например:

struct {
    int foo;
    double bar;
} baz;
unsigned char *bytes = (void *)&baz;

// Do stuff with the baz structure.

// Do things with the bytes array.

Конечно, размер должен быть отслежен, но это в первую очередь законно, или он относится к сфере, определяемой реализацией или неопределенным поведением?

Я спрашиваю, потому что я реализую алгоритм, аналогичный qsort, и я хотел бы, чтобы он работал для любого массива, независимо от типа, так же, как qsort делает.

1 ответ

Решение

6.5 Выражения

[...]
6 Эффективным типом объекта для доступа к его сохраненному значению является объявленный тип объекта, если таковой имеется.87) Если значение сохраняется в объекте, у которого нет объявленного типа, через lvalue, имеющий тип, который не является символом type, тогда тип lvalue становится эффективным типом объекта для этого доступа и для последующих обращений, которые не изменяют сохраненное значение. Если значение копируется в объект, не имеющий объявленного типа, с использованием memcpy или memmove, или копируется как массив символьного типа, тогда эффективный тип измененного объекта для этого доступа и для последующих доступов, которые не изменяют значение, является действующий тип объекта, из которого копируется значение, если оно есть. Для всех других доступов к объекту, не имеющему объявленного типа, эффективный тип объекта - это просто тип lvalue, используемого для доступа.
7 Объект должен иметь свое сохраненное значение, доступ к которому осуществляется только через выражение lvalue, имеющее один из следующих типов:88)

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

Акцент мой. Таким образом, вы можете рассматривать любой тип как массив символов (unsigned char[], char[] или же signed char[]).

Я также процитировал пункт 6, потому что он делает обратное неприменимым.

Другие вопросы по тегам