Обдумывая контрпример для этого вопроса, я придумал:
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
? То есть, можем ли мы написать следующее без вызова UB?
u.a.y = 42;
std::cout << u.b.y;
(также приветствуются ответы на C ++ 1y / "исправленный C ++ 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
неопределенное поведение (чтение из неинициализированного объекта).
int
иchar
имеет выравниваниеint
. Атрибутalignas(2)
дляchar byte
в качестве первого элемента не работает, потому что этот первый элемент уже имеетalignas(int)
выравнивание. Возможно, лучший пример:struct A {int x; alignas(double) char byte;};
- person David Hammen   schedule 01.02.2014alignas
является частью type-id или нет? В некоторых местах кажется, что это так, в других кажется, что это определенно не так. - person David Hammen   schedule 02.02.2014static_assert(std::is_same<decltype(A::byte), char>::value, "!");
, который затем приводят к этому вопросу. - person dyp   schedule 02.02.2014alignas
на своих элементах, не предназначен для использования в стандартной компоновке, тогдаsizeof(A)
может быть равно четырем, причем второй член находится со смещением 0, а первый - со смещением 2. Несколько более уместное примечание: текущая формулировка стандартный макет, который уже делает буквальные требования невыполнимыми по другим причинам. Подробности здесь. Я искал открытые проблемы по поводу выравнивания тоже, но ничего интересного не нашел. - person   schedule 23.02.2014union
s. - person dyp   schedule 03.05.2014