Неправильно описаны анонимные структуры и союзы в C11?
Говорит стандарт C, касающийся анонимных структур и объединений:
6.7.2.1 p13. Неименованный элемент, спецификатор типа которого является спецификатором структуры без тега, называется анонимной структурой; неназванный член, спецификатор типа которого является спецификатором объединения без тега, называется анонимным объединением. Члены анонимной структуры или объединения считаются членами структуры или объединения. Это применяется рекурсивно, если содержащая структура или объединение также анонимны.
Обратите внимание на акцент: вместо того, чтобы члены анонимной структуры/объединения находились в рамках структуры struct/union, они полностью являются ее членами. Но к этому относятся обязанности:
6.7.2.1 p16. Размер объединения достаточен для того, чтобы содержать самый большой из его членов. Значение не более одного из членов может быть сохранено в объединенном объекте в любое время. Указатель на объект объединения, соответствующим образом преобразованный, указывает на каждый из его членов (или член является битовым полем, а затем на единицу, в которой он находится) и наоборот.
В совокупности они, похоже, подразумевают, что члены анонимной структуры внутри (названного) союза ведут себя как совпадающие, взаимоисключающие члены союза. Таким образом, следующее должно работать:
union Foo
{
struct
{
char a;
char b;
};
};
int main(void) {
union Foo f;
assert(&f == &(f.a) && &f == &(f.b));
}
Конечно, этого не происходит, и мы не хотим, чтобы это... не было никаких причин для анонимных структур/союзов, если бы они работали, как указано выше. Тем не менее, Стандарт кажется однозначным в этом вопросе. Есть что-то, что мне не хватает?
Ответы
Ответ 1
TL; DR
Это выглядит как формулировка, они не должны пересекаться.
подробности
Это описано в отчете о дефектах (DR) 499, в котором говорится:
Учитывая следующий код:
union U {
struct {
char B1;
char B2;
char B3;
char B4;
};
int word;
} u;
Сохраняется ли хранение B1, B2, B3 и B4?
Согласно 6.7.2.1 # 13, члены должны пересекаться на складе, поскольку они становятся членами "союза U".
По крайней мере, одна реализация (GCC), по-видимому, НЕ считает их перекрывающимися.
По крайней мере, одна реализация (IBM XL LE AIX) считает их перекрывающимися по мере того, как в настоящее время указывается стандарт.
И ответ комитетов был:
Хранилище не перекрывается.
Связанная с этим проблема находится в DR 502, и оба могут быть разрешены с согласованными изменениями в формулировках.
а также
Изменить §6.7.2.1 p13 из:
Неименованный элемент типа структуры без тега называется анонимной структурой; неназванный член типа union без тега называется анонимным объединением. Члены анонимной структуры или объединения считаются членами структуры или объединения. Это применяется рекурсивно, если содержащая структура или объединение также анонимны.
чтобы:
Неименованный элемент типа структуры без тега называется анонимной структурой; неназванный член типа union без тега называется анонимным объединением. Имена членов анонимной структуры или объединения добавляются в пространство имен содержащей структуры или объединения. Это применяется рекурсивно, если содержащая структура или объединение также анонимны.
будет адекватно решать проблему.