В стеке компилятор может выполнять множество оптимизаций, поскольку контекст является статическим и известен во время компиляции, но при работе с доступом к динамически выделенным объектам и, как правило, доступ к "по ссылке", контекст неизвестен, поэтому логически в в таких случаях доступ к членству сводится к разыменованию адреса памяти, полученного путем добавления базового адреса объекта и смещения для этого члена. Или это? Я новичок в этом, поэтому на данный момент я только угадываю и, вероятно, не хватает подробностей.
Например, я заметил, что если я реализую оператор +
как void add(int * a, int * b, int * r);
при работе с членами стека (и с использованием оператора &
) код сборки идентичен тому, что создается оператором регулярного +
, поэтому кажется, что указатели, которые, как известно, указывают на известные значения времени компиляции, оптимизированы для исключения дополнительных разыменований ( и копирование), а непрямые функции add()
встроены как прямой доступ к объектам стека. Означает ли это, что компилятор "достаточно хорош", чтобы иметь возможность оптимизировать, например, аксессоры, реализованные с косвенностью из постоянных смещений значения из базового адреса объекта в стеке, как если бы с использованием доступа к членству в структуре для получения этого значения?
Я не знаю, как вы внедрили тело функции, чтобы этот ответ мог быть полностью выключен :).
Если вы добавляете внутри своей функции r = a + b, код будет выглядеть одинаково, но не будет одинаковым.
для прототипа (int *, int *, int *) вы добавите указатели, что неверно. Чтобы получить целочисленное значение внутри вашей функции, тело должно быть:
*r = *a + *b ;
ИЛИ
r[0] = a[0] + b[0];
чтобы получить то значение, которое вы желаете. Этот орган не должен иметь тот же код сборки, что и оператор +, поскольку указанные значения не известны во время компиляции.
для прототипа (int &, int &, int &) и тела
r = a + b;
компилятор включит эту функцию, так что да, сборка должна быть indentical.
add()
реализована с использованием косвенного указателя, например, *r = *a + *b;
, Компилятор генерирует идентичную сборку как оператор +
только если функция встроена в статическом контексте, указывающем на известные объекты стека. Код идентичен инструкции для инструкции. Несмотря на то, что функция использует внутренние указатели, компилятор может сказать, что в скомпилированном контексте они указывают на объекты стека, поэтому компилятор обращается к тем, кто использует стек, а не тратит время на копирование указателей и косвенную оттуда.