Совместимы ли структуры переменных одного и того же типа с структурой, содержащей массив этого типа?
Совместимы ли эти 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
,