В последнее время я анализировал некоторые части более старого кода, где в некоторых случаях значение, возвращаемое функцией, было присвоено переменной const
, а иногда и const&
. Из любопытства я переключился на разборку, чтобы увидеть различия. Но прежде, чем добраться до точки, позвольте мне сделать простой пример, чтобы иметь некоторый код для обозначения:Возвращаемое значение const & and const назначение - дизассемблирование
struct Data
{
int chunk[1024];
};
Data getData()
{
return Data();
}
int main()
{
const std::string varInit{ "abc" }; // 1
const std::string varVal = "abc"; // 2
const std::string& varRef = "abc"; // 3
const Data dataVal = getData(); // 4
const Data& dataRef = getData(); // 5
return 0;
}
Следующая разборку выше код был приобретен с VS2015 с оптимизациями отключенными.
Я не специалист ASM, но на первый взгляд, я бы сказал, что для (1)
и (2)
есть подобные операции, выполняемые. Тем не менее, я удивлен тем, что (3)
выполняет две дополнительные операции (lea
и mov
) по сравнению с предыдущими версиями, где const&
не использовался при присвоении значения переменной.
То же самое можно наблюдать, когда данные возвращаются из функции по значению. (5)
выполняет еще две операции по отношению к (4)
.
на вопросы довольно узкий:
- Где эти дополнительные операции берутся и какова их цель здесь? В общем не так, как здесь: What's the purpose of the LEA instruction, но в представленном контексте.
- Может ли это повлиять на производительность, по крайней мере, для объектов, для которых размер подстилающих данных ничтожно мал? (в отличие от структуры
Data
, используемой в примере) - Может ли это повлиять на оптимизацию? (Для выпуска сборки)
Кстати, я уже читал Why not always assign return values to const reference? о преимуществах и недостатках использования сопзЬ и сопзИте & при присвоении значения, которые могут быть несколько связанными, но не является частью вопроса.
Ваш компилятор реализованного 'varRef' ссылка как обычный«указатель в маскировке». Инструкция 'lea' вычисляет начальное значение для этого указателя (' ecx = ebp - 84h'), тогда как команда 'mov' сохраняет это значение в указателе' varRef'. – AnT