Псевдоним целых чисел со знаком и без знака во время оптимизации

Аsigned&не может быть инициализирован из (и наоборот), но строгие правила алиасинга позволяют читать/записыватьsignedобъект черезunsigned&(и наоборот), см. стандарт C++20 [basic.lval]#11.2 . Теоретически это можно использовать при оптимизации компилятора, если правило «как если бы» не нарушается.

Пример 1. Если я прав,fможет быть реализовано простым переходом к:

      void foo(const unsigned& u);

void f(const signed& par)
{
    foo(par);
}

Но все компиляторы загружаютparв регистр, сохранить регистр в стеке и передать местоположение стека вfoo. Живая демонстрация.

Пример 2. Аналогично думаюg1иg2может указывать на одно и то же место в памяти:

      const signed&   g1 = 1;
const unsigned& g2 = g1;

Но компиляторы склонны выделять два разных места. Живая демонстрация.

Вопрос. Почему это? Разве это не упущенная возможность для оптимизации?

1 ответ

       const signed&   g1 = 1;
const unsigned& g2 = g1;

Но компиляторы склонны выделять два разных места.

Здесь происходит то, что преобразуется во временныйunsigned intи привязывается к этому временному. А C++ гарантирует, что разные объекты имеют разные адреса, поэтомуg1иg2нужно хранить отдельно.

То же самое с вашим примером функции. Ключевым моментом является то, что наличие разных адресов является наблюдаемым поведением. Эти функции могут полагаться на тот факт, что их аргументы имеют разные адреса, поскольку они являются ссылками на разные объекты. Если бы ваш компилятор объединил разные объекты в одно и то же пространство памяти, это наблюдаемое поведение изменилось бы, поэтому оно не подпадает под правило «как если бы».

Другие вопросы по тегам