Объединение с константой и непостоянством?
Это выглядит как undefined поведение
union A {
int const x;
float y;
};
A a = { 0 };
a.y = 1;
В спецификации указано
Создание нового объекта в месте хранения, в котором находится объект const со статической, потоковой или автоматической продолжительностью хранения, или в месте хранения, которое такой объект const, который использовался для его завершения до его окончания жизни, приводит к поведению undefined.
Но никакой компилятор не предупреждает меня, пока он легко диагностирует ошибку. Я неверно истолковал формулировку?
Ответы
Ответ 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, а также на С++, так что это было некоторое время).