2012-03-17 8 views
14

Этот код нарушает строгий псевдоним?Имеет ли доступ к первому полю структуры с помощью C cast нарушает строгий псевдоним?

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

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

+2

V-столы потенциально могут быть первыми, поэтому это территория UB. – ildjarn

+1

@ildjarn, vtables не существует в C – bdonlan

+4

@bdonlan: Это также помечено 'C++'. ; -] – ildjarn

ответ

24

Во-первых, это законно бросить в С. §6.7.2.1/13:

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

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

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

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

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

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

+0

C++ определенно не будет документировать наличие vtable, но я применяю это только в случаях без такой странности. –

+0

@ Geoffrey: "* случаи без такой странности *". Ака тривиально копируемые типы? Ака-то, о чем вы должны были упомянуть в своем вопросе? – ildjarn

+1

Ну, в этом вопросе упоминается, что у структуры есть одно int-поле, которое, помимо прочего, не подразумевает vtable. Название уже довольно многословное. –