Доступ к первому полю структуры через приведение C нарушает строгий псевдоним? - PullRequest
15 голосов
/ 17 марта 2012

Этот код нарушает строгий псевдоним?

struct {int x;} a;
*(int*)&a = 3

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

1 Ответ

25 голосов
/ 17 марта 2012

Во-первых, разрешено разыгрывать в C. §6.7.2.1 / 13:

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

Правило наложения имен выглядит следующим образом (§6.5 / 7):

Объект должен иметь свое сохраненное значение, доступное только через выражение lvalue, которое имеет одно из следующие типы:

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

Здесь вы будете получать к нему доступ через указатели «типа, совместимого с действующим типом объекта» и «агрегатного или объединенного типа, который включает в себя один из вышеупомянутых типов среди его членов», так что никаких проблем с псевдонимами также не возникает. Таким образом, в Си действительно совершенно законно получить доступ к первому члену структуры, приведя указатель на структуру к типу рассматриваемого члена.

В C ++, однако, вы часто найдете vtables и другие вещи в начале объекта C ++. Однако в вашем конкретном случае ваша структура имеет стандартную компоновку, и это явно разрешено (§9.2 / 20 в n3290, благодаря Люку Дантону! - C ++ 03, очевидно, имеет аналогичное правило, выраженное в терминах объектов POD) .

...