Ответ 1
К сожалению, я верю, что ответ на этот вопрос заключается в том, что эта операция над объединениями указана в С++, хотя самоопределение полностью нормально.
Самоопределение - это четко определенное поведение, если мы посмотрим на проект стандартного раздела С++ 1.9
В пункте 15 выполнения программы есть следующие примеры:
void f(int, int);
void g(int i, int* v) {
i = v[i++]; // the behavior is undefined
i = 7, i++, i++; // i becomes 9
i = i++ + 1; // the behavior is undefined
i = i + 1; // the value of i is incremented
f(i = -1, i = -1); // the behavior is undefined
}
и самоопределение рассматривается в примере i = i + 1
.
Проблема в том, что в отличие от C89 вперед, которая поддерживает тип-punning в С++, это неясно, Мы знаем только, что:
В объединении не более одного нестатического элемента данных могут быть активны в любое время
но поскольку это обсуждение в список рассылки исследовательской группы WG21 UB показывает, что эта концепция не совсем понятна, у нас есть следующие комментарии:
Хотя стандарт использует термин "активное поле", он не определяет его
и указывает на это ненормативное примечание:
Примечание. В общем, нужно использовать явные вызовы деструктора и назначить новые операторы для изменения активного члена объединения. - конец примечания
поэтому нам нужно задаться вопросом:
b = a;
делает b
активным членом или нет? Я не знаю, и я не вижу способа доказать это с помощью любой из текущих версий проекта стандарта.
Несмотря на то, что большинство современных компиляторов, например gcc, поддерживает тип-punning в С++, что означает, что вся концепция активный элемент обходит.