Возможно ли, чтобы следующее утверждение потерпело неудачу с любым компилятором на любой архитектуре?
union { int x; int y; } u;
u.x = 19;
assert(u.x == u.y);
Возможно ли, чтобы следующее утверждение потерпело неудачу с любым компилятором на любой архитектуре?
union { int x; int y; } u;
u.x = 19;
assert(u.x == u.y);
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:. Для упрощения использования союзов предусмотрена одна специальная гарантия: если соединение содержит несколько структур, которые имеют общую начальную последовательность (см. ниже), и если объединение объект в настоящее время содержит одну из этих структур, разрешено проверять общие начальной части любого из них в любом месте, где декларация полного типа объединения видимый. Две структуры имеют общую начальную последовательность, если соответствующие члены имеют совместимые типы (и для бит-полей, одинаковые ширины) для последовательности одного или нескольких начальные элементы.
Однако я не смог найти сопоставимую гарантию для неструктурированных типов внутри объединения. Однако это может быть упущением: если стандарт имеет несколько длины, чтобы описать, что должно происходить со структурированными типами, которые не являются одинаковыми, он должен был прояснить одну и ту же точку для более простых, неструктурированных типов.
Проблема 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 является неофициальным проектом, но легко доступен в сети.)
Я считаю, что этот вопрос очень сложно ответить так, как вы ожидаете.
Насколько я знаю, чтение одного поля union
, которое не было последним, связано с undefined.
Таким образом, невозможно ответить "нет", так как любой автор компилятора может свободно обнаруживать это и заставить его терпеть неудачу только из-за злобы, если им это нравится.