Подтвердить что ты не робот

Объединение с константой и непостоянством?

Это выглядит как undefined поведение

union A {
  int const x;
  float y;
};

A a = { 0 };
a.y = 1;

В спецификации указано

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

Но никакой компилятор не предупреждает меня, пока он легко диагностирует ошибку. Я неверно истолковал формулировку?

4b9b3361

Ответ 1

В последнем черновом стандарте С++ 0x указано следующее:

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

Итак, ваше утверждение

a.y = 1;

отлично, потому что он изменяет активный член от x до y. Если впоследствии вы указали a.x как rvalue, поведение будет undefined:

cout << a.x << endl ; // Undefined!

Ваша цитата из спецификации здесь не уместна, потому что вы не создаете никакого нового объекта.

Ответ 2

Если это какое-то утешение - компилятор Microsoft Xbox 360 (который основан на компиляторе Visual Studio) делает ошибку. Что смешно, потому что это обычно самое мягкое из группы.

error C2220: warning treated as error - no 'object' file generated
warning C4510: 'A' : default constructor could not be generated
    : see declaration of 'A'
warning C4610: union 'A' can never be instantiated - user defined constructor required

Эта ошибка исчезает, если я уберу const. Компиляторы на основе gcc не жалуются.

EDIT: компилятор Microsoft Visual С++ имеет такое же предупреждение.

Ответ 3

На самом деле нет смысла иметь const члена union, и я удивлен, что стандарт позволяет это. Цель всех многих ограничений на то, что может войти в union, - это добраться до точки, где побитовое присвоение будет действительным оператором присваивания для всех членов, и вы не можете использовать побитовое присвоение для назначения const int. Я предполагаю, что это просто случай, о котором никто раньше не думал (хотя он влияет на C, а также на С++, так что это было некоторое время).