Вызовы функций
Компилятор выполнит одно из следующих действий:
- Перенесет аргумент в стек и вызовет функцию
- Для более сложной функциичем у вас, это обычно происходит.
- Загрузите аргумент в регистр и вызовите функцию
- Это может произойти при оптимизации, и тамдостаточно регистров для хранения переменных, которые необходимо передать.
- Оптимизация функции полностью (встраивание)
- Для тривиальной функции, такой как в вашем случае,нормальный компилятор сделает это с самым базовым уровнем оптимизации, так что вы получите ту же сборку, как если бы вы сделали
int a = 3
.
Справочные переменные в C ++
Ссылочная переменная, объявленная в вашем коде как int &a
, - это «другое имя для существующей области памяти».Поэтому объявление int &a
нигде не выделяет место для int
.Он просто объявляет a
для ссылки на уже выделенную область памяти.
Это местоположение может быть существующей переменной int b
, так что вы говорите:
int b;
int &a = b;
Здесь, a
будет ссылаться на то же содержание, что и b
.«Новое имя для существующего объекта» - хорошая идиома.
Можно придумать и сказать int &a = array[5]
, так что a
относится к 6-му элементу int
массива * 1047.* или int &a = *(int*)0x12345678
для обозначения определенной области памяти, но я отвлекся.
Ваш код
int &a = 3;
не может работать, поскольку 3
- это временный объект, которыйбудут забыты после выполнения заявления.Чтобы понять проблему более фундаментально, подумайте об этом: Если a
относится к уже выделенной ячейке памяти, на что она будет ссылаться после выполнения оператора int &a = 3
, и временного объекта * 1058 больше нет*?
Это также распространенная проблема со ссылочными переменными в функциях: возвращение ссылки на локальный объект-функция - неопределенное поведение ... но я снова отвлекся.У вас всегда должен быть «живой, выделенный объект» для a
, на который можно сослаться, конец истории.
Чуть более подробно о ссылочных переменных
Что обычно происходит дляОператор типа
int a = 3;
состоит в том, что компилятор генерирует код (упрощенно):
- загружает постоянную 3 в регистр
- загружает регистр в памятьрасположение, выделенное для
Суть в том, что ни в одном случае не существует долгоживущей ячейки памяти, выделенной для объекта 3
, поэтому int &a
действительно нельзя сделать, чтобы сослаться на этообъект из-за этого.
«долгоживущая ячейка памяти» означает ячейку, которая будет жить после операции присваивания.Регистр, в котором хранится 3, будет перезаписан и повторно использован, вероятно, сразу после операции присваивания, поэтому он даже теоретически не подходит для цели int &a
(на практике int &a
можно сделать тольков любом случае ссылается на память , а не регистр).