Как ранее установленный, объединение формы
union some_union {
type_a member_a;
type_b member_b;
...
};
с n членами содержит n + 1 объектов в перекрывающемся хранилище: один объект для самого союза и один объект для каждого члена объединения. Понятно, что вы можете свободно читать и писать любому члену профсоюза в любом порядке, даже если вы читаете член профсоюза, который не был последним. Строгое правило сглаживания никогда не нарушается, так как значение, через которое вы получаете доступ к хранилищу, имеет правильный эффективный тип.
Это в дальнейшем поддерживается в сноске 95, в которой объясняется, как использование типа punning является предполагаемым использованием союзов.
Типичным примером оптимизаций, разрешенных правилом строгого псевдонимов, является эта функция:
int strict_aliasing_example(int *i, float *f)
{
*i = 1;
*f = 1.0;
return (*i);
}
который компилятор может оптимизировать для чего-то вроде
int strict_aliasing_example(int *i, float *f)
{
*i = 1;
*f = 1.0;
return (1);
}
поскольку он может с уверенностью предположить, что запись в *f
не влияет на значение *i
.
Однако, что происходит, когда мы передаем два указателя членам одного и того же союза? Рассмотрим этот пример, предполагая типичную платформу, где float
- это число с плавающей запятой с одиночной точностью IEEE 754, а int
- 32-битное целое число из двух дополнений:
int breaking_example(void)
{
union {
int i;
float f;
} fi;
return (strict_aliasing_example(&fi.i, &fi.f));
}
Как было установлено ранее, fi.i
и fi.f
относятся к области перекрывающейся области памяти. Чтение и запись их безусловно легально (запись разрешена только после того, как союз был инициализирован) в любом порядке. На мой взгляд, ранее обсуждавшаяся оптимизация, выполняемая всеми основными компиляторами, дает неправильный код, поскольку два указателя разного типа юридически указывают на одно и то же местоположение.
Я почему-то не могу поверить, что моя интерпретация строжайшего правила сглаживания верна. Не представляется правдоподобным, что сама оптимизация, на основе которой было построено строгое наложение, невозможна из-за вышеупомянутого углового случая.
Скажите, пожалуйста, почему я ошибаюсь.
A связанный вопрос появился во время исследования.
Пожалуйста, прочитайте все существующие ответы и их комментарии, прежде чем добавлять свои собственные, чтобы убедиться, что ваш ответ добавляет новый аргумент.