Совместимы ли структуры переменных одного и того же типа с структурой, содержащей массив этого типа?

Совместимы ли эти 2 структуры с макетом?

struct One {
    float x, y, z;
};

struct Two {
    float c[3];
};

Оба содержат 3 числа с плавающей запятой, так что это описание можно считать истинным (из N3797):

16 Два типа структуры стандартного макета (раздел 9) совместимы с макетом, если они имеют одинаковое количество элементов нестатических данных, а соответствующие элементы нестатических данных (в порядке объявления) имеют типы, совместимые с макетом (3.9).

N4659 имеет другой текст:

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

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

Если ответ " нет", они не совместимы с макетом, тогда: было ли это намерением комитета? Может быть, они хотят One а также Two быть совместимым с макетом (возможно, член комитета читает это и может уточнить).


Бонусный вопрос: гарантируется ли, что sizeof(One)==sizeof(Two)?

2 ответа

Решение

Ну нет:

[...] если у них одинаковое количество нестатических элементов данных [...]

One имеет три члена: x, y, а также z, Two имеет одного члена: c, Они не имеют одинакового количества нестатических элементов данных, поэтому они не совместимы с макетом.


Новая формулировка отличается, но вы в конечном итоге на том же месте. [basic.types] определяет совместимость с макетом как:

Два типа cv1 T1 и cv2 T2 являются типами, совместимыми с макетом, если T1 и T2 являются одним и тем же типом, перечислениями, совместимыми с макетом, или типами классов, совместимыми с макетом.

[class.mem] определяет макеты, совместимые классы:

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

Где общая начальная последовательность:

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

Здесь первый член One (float x) несовместима с первым элементом Two (float c[3]), поэтому общая начальная последовательность пуста.

Компилятору разрешено добавлять отступы между членами в class или же struct,

Элементы массива находятся в смежных местах.

Они могут быть несовместимы с макетом в зависимости от того, как компилятор организует элементы в struct,

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