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

Что означает стандарт C о объединении двух одинаковых типов

Возможно ли, чтобы следующее утверждение потерпело неудачу с любым компилятором на любой архитектуре?

union { int x; int y; } u;
u.x = 19;
assert(u.x == u.y);
4b9b3361

Ответ 1

C99 Делает специальную гарантию для случая, когда два члена объединения являются структурами, которые разделяют начальную последовательность полей:

struct X {int a; /* other fields may follow */ };
struct Y {int a; /* other fields may follow */ };
union {X x; Y y;} u;
u.x.a = 19;
assert(u.x.a == u.y.a); // Guaranteed never to fail by 6.5.2.3-5.

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

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

Ответ 2

Проблема assert в этой проблеме никогда не завершится неудачей при реализации стандартного C, так как для доступа к u.y после назначения u.x требуется переинтерпретировать байты u.x как тип u.y. Поскольку типы те же, переинтерпретация дает одинаковое значение.

Это требование отмечено в C.11 (N1570) 6.5.2.3 примечание 95, которое указывает, что оно вытекает из пункта 6.2.6, которое охватывает представления типов. В примечании 95 говорится:

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

(N1570 является неофициальным проектом, но легко доступен в сети.)

Ответ 3

Я считаю, что этот вопрос очень сложно ответить так, как вы ожидаете.

Насколько я знаю, чтение одного поля union, которое не было последним, связано с undefined.

Таким образом, невозможно ответить "нет", так как любой автор компилятора может свободно обнаруживать это и заставить его терпеть неудачу только из-за злобы, если им это нравится.