Союз макетов совместимых типов - PullRequest
0 голосов
/ 29 октября 2018

Посмотрите на этот код:

struct A {
    short s;
    int i;
};
struct B {
    short s;
    int i;
};

union U {
    A a;
    B b;
};

int fn() {
    U u;
    u.a.i = 1;
    return u.b.i;
}

Гарантируется ли, что fn() возвращает 1?

Примечание: это дополнительный вопрос к this .

1 Ответ

0 голосов
/ 29 октября 2018

Да, это определенное поведение. Сначала давайте посмотрим, что говорит стандарт о A и B. [class.prop] / 3 имеет

Класс S является классом стандартной компоновки, если он:

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

Итак, A и B являются стандартными типами макетов. Если мы посмотрим на [class.mem] / 23

Два типа структуры стандартного макета являются классами, совместимыми с макетом, если их общая начальная последовательность включает в себя все члены и битовые поля обоих классов ([basic.types]).

и [class.mem] / 22 * ​​1038 *

Общая начальная последовательность двух типов структур стандартного макета представляет собой самую длинную последовательность нестатических элементов данных и битовых полей в порядке объявления, начиная с первого такого объекта в каждой из структур, так что соответствующие объекты имеют макет -совместимых типов, либо оба объекта объявлены с атрибутом no_unique_address ([dcl.attr.nouniqueaddr]), либо ни один из них не является, и либо оба объекта являются битовыми полями с одинаковой шириной, либо ни один не является битовым полем.

и [class.mem] / 25

В объединении стандартной компоновки с активным членом типа структуры T1 разрешается читать нестатический член данных m другого члена объединения типа структуры T2, если m является частью общей начальной последовательности T1 и Т2; поведение такое, как если бы соответствующий член T1 был назначен. [Пример:

struct T1 { int a, b; };
struct T2 { int c; double d; };
union U { T1 t1; T2 t2; };
int f() {
  U u = { { 1, 2 } };   // active member is t1
  return u.t2.c;        // OK, as if u.t1.a were nominated
}

- конец примера] [Примечание. Чтение энергозависимого объекта через glvalue энергонезависимого типа имеет неопределенное поведение ([dcl.type.cv]). - конец примечания]

Тогда мы имеем, что классы имеют одинаковую общую начальную последовательность, расположены одинаково, и доступ к одному и тому же члену неактивного типа рассматривается как доступ к этому члену активного типа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...