Поскольку в этом примере весь код виден компилятору, компилятор может гипотетически определить, что запрашивается, и сгенерировать требуемый код сборки.Однако демонстрация одной ситуации, в которой строгое правило псевдонима не является теоретически необходимым, ничего не доказывает, что нет других ситуаций, где это необходимо.
Подумайте, содержит ли вместо этого код:
foo(&val, ptr)
, где объявление foo
равно void foo(uint64_t *a, uint32_t *b);
.Тогда внутри foo
, который может находиться в другой единице перевода, компилятор не сможет узнать, что a
и b
указывают (части) на один и тот же объект.
Тогда естьдва варианта: во-первых, язык может разрешить псевдонимы, и в этом случае компилятор, переводя foo
, не может выполнить оптимизацию, полагаясь на то, что *a
и *b
различны.Например, всякий раз, когда что-то записывается в *b
, компилятор должен сгенерировать ассемблерный код для перезагрузки *a
, поскольку это могло измениться.Оптимизации, такие как хранение копии *a
в регистрах при работе с ней, не допускаются.
Второй вариант, два, - запретить алиасы (в частности, не определять поведение, если программа это делает).).В этом случае компилятор может выполнить оптимизацию, полагаясь на то, что *a
и *b
различаются.
Комитет C выбрал второй вариант, поскольку он предлагает лучшую производительность, не ограничивая чрезмерно программистов.