2016-03-17 2 views
9

Вид, связанный с my previous question:Элементы массива считаются общей начальной последовательностью?

Элементы массивов считаются обычной исходной последовательностью?

struct arr4 { int arr[4]; }; 
struct arr2 { int arr[2]; }; 

union U 
{ 
    arr4 _arr4; 
    arr2 _arr2; 
}; 

U u; 
u._arr4.arr[0] = 0; //write to active 
u._arr2.arr[0]; //read from inactive 

В соответствии с this cppreference page:

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

Будет ли это законным, или это также было бы незаконным тиражом?

+1

Без всяких аргументов я считаю, что это законно. – knivil

ответ

4

C++ 11 говорит (9.2):

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

Что касается того, массивов разного размера образуют действительную общую начальную последовательность, 3.9 говорит:

Если два типа Т1 и Т2 имеют одинаковый тип, то T1 и T2 макет-совместимые типы

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

На практике, однако, я не знаю компилятор (GCC), который:

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

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

+1

Но массивы являются частью 'struct' и поэтому являются членами. – knivil

+0

@davmac. Читайте вопрос - 'U' содержит один' arr4' и один 'arr2', в то время как эти имена могут вводить в заблуждение, они определяются как' struct' чуть выше. – Holt

+0

@ Холл да, неправильно прочитайте его. Однако окончательный ответ («нет») тот же. Я объяснил, почему. – davmac

Смежные вопросы