Придумав встречный пример для этого вопроса, я придумал:
struct A
{
alignas(2) char byte;
};
Но если этот законный и стандартный макет, совместим ли он с этим struct B
?
struct B
{
char byte;
};
Кроме того, если мы имеем
struct A
{
alignas(2) char x;
alignas(4) char y;
};
// possible alignment, - is padding
// 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
// x - - - y - - - x - - - y - - -
struct B
{
char x;
char y;
}; // no padding required
union U
{
A a;
B b;
} u;
Существует ли общая начальная последовательность для A
и B
? Если да, включает ли он A::y
и B::y
? I.e., мы можем написать следующее w/o, вызывающее UB?
u.a.y = 42;
std::cout << u.b.y;
(ответы для С++ 1y/ "fixed С++ 11" также приветствуются)
-
См. [basic.align] для выравнивания и [dcl.align] для спецификатора выравнивания.
-
[basic.types]/11 говорит для фундаментальных типов "Если два типа
T1
иT2
являются одним и тем же типом, тоT1
иT2
являются совместимыми с макетами типами." (основной вопрос заключается в том, имеют лиA::byte
иB::byte
типы совместимости с макетами) -
[class.mem]/16 "Два типа структуры стандартного макета совместимы с макетами, если они имеют одинаковое количество нестатических элементов данных и соответствующих нестатических членов данных (в порядке объявления) имеют макет -собираемые типы."
-
[class.mem]/18 "Две структуры стандартного компоновки имеют общую начальную последовательность, если соответствующие члены имеют совместимые с макетами типы, и ни один из них не является битовым полем или оба являются битовыми полями с одинаковой шириной для последовательности одного или нескольких начальных элементов. "
-
[class.mem]/18 "Если объединение стандартного макета содержит две или более структуры стандартного макета, которые имеют общую начальную последовательность, и если объект объединения стандартного макета в настоящее время содержит одну из этих структур стандартной компоновки, это разрешено для проверки общей исходной части любого из них ".
Конечно, на уровне юрисконсульта другой вопрос заключается в том, что это означает, что проверка общей исходной последовательности "разрешена". Я предполагаю, что какой-то другой абзац мог бы сделать описанное выше поведение u.b.x
undefined (чтение из неинициализированного объекта).