Тип ссылки и указатель в разборке - PullRequest
3 голосов
/ 01 октября 2009

Почему ссылочные типы и указатели одинаковы в скомпилированном коде? (Вы можете увидеть в третьей и четвертой строке). Я пытался понять это, но, видимо, я не смог добиться.

Если переменная ссылочного типа должна быть инициализирована при объявлении и не может быть изменена, то есть ли необходимость выполнять косвенное обращение, как в указателях?

int x = 10;

mov dword ptr [x], 0Ah

int y = x;

mov eax, dword ptr [x]

mov dword ptr [y], eax

int &i = y;

lea eax, [y]

mov dword ptr [i], eax

int *p = &x;

Lea Eax, [X]

mov dword ptr [p], eax

p = &i;

mov eax, dword ptr [i]

mov dword ptr [p], eax

x = i;

mov eax, dword ptr [i]

mov ecx, dword ptr [eax]

mov dword ptr [x], ecx

Ответы [ 5 ]

2 голосов
/ 01 октября 2009

Если компилятору известно, что ссылка всегда ссылается на один конкретный объект / элемент, то компилятор, безусловно, может оптимизировать косвенное указание.

Однако большинство ссылок фактически связаны во время выполнения. Даже если конкретный экземпляр ссылки не может быть восстановлен, разные исполнения конкретной области или разные экземпляры объекта, который содержит ссылочные элементы, могут выполняться со ссылкой, связанной с различным объектом для каждого из этих экземпляров. Использование косвенного обращения - удобный способ для компилятора справиться с этим.

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

Кроме того, я подозреваю, что вы не включаете оптимизацию компилятора - используя свой код и вызывая различные функции с y и i и их адресами, быстрый тест в VC ++ 2005 с оптимизацией показывает, что компилятор не реализация i в качестве указателя, но в качестве истинного псевдонима для y (т. е. всякий раз, когда передается i или &i, компилятор использует адрес y напрямую).

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

2 голосов
/ 01 октября 2009

Ссылки - это не что иное, как ограниченные указатели. Разница лишь в том, что они должны указывать на существующую переменную. Вы можете обойти это в C ++, но гораздо сложнее пропустить:

int& r = *(reinterpret_cast<int*>(0x0));

Конечно, это неопределенное поведение!

Итак, в основном они реализованы как указатели. Они отличаются в использовании во многих местах, например. ссылки автоматически разыменовываются, когда они представляют собой r-значения или l-значения:

int x = 0;

int& r = x; // 1) no need to take the address of x like &x

r = r * x; // Manually: (*r) = (*r) * x

Они обеспечивают более безопасную альтернативу необработанным указателям. Кроме того, они имеют гораздо более элегантный синтаксис, чем необработанные указатели. Просто представьте, что у вас нет ссылок при перегрузке операторов класса.

Таким образом, они являются указателями с ограниченным доступом, с лучшим / более безопасным псевдонимом, но с ограниченной функциональностью.

1 голос
/ 01 октября 2009

C ++ FAQ Lite дает хорошее объяснение того, что вы видите: https://isocpp.org/wiki/faq/references

По сути, в двух словах, компилятор по существу рассматривает его как указатель, он использует адрес объекта и выполняет разыменование для вас.

1 голос
/ 01 октября 2009

Ссылка представлена ​​внутри как указатель. Это компилятор , который накладывает ограничения на инициализацию и невозможность повторного использования.

Если переменная ссылочного типа должна быть инициализируется при объявлении и не может изменить, так что есть ли необходимость делать косвенность как в указателях?

Единственной альтернативой является копирование значения, а не ссылка. Ссылка действует аналогично указателю: она сохраняет местоположение объекта. Разница в том, что ссылка действует как сам объект, а не требует явной разыменования.

0 голосов
/ 10 октября 2009

Да, ссылки являются просто синтаксическим сахаром для указателей (с ограничениями, соответствующими новому синтаксису). Это также позволяет C ++, по-видимому, иметь передачу параметров копирования по ссылке, в отличие от C, который имеет только копирование по значению (даже параметры указателя)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...