Доступ к члену через указатель на объект

0

В стеке компилятор может выполнять множество оптимизаций, поскольку контекст является статическим и известен во время компиляции, но при работе с доступом к динамически выделенным объектам и, как правило, доступ к "по ссылке", контекст неизвестен, поэтому логически в в таких случаях доступ к членству сводится к разыменованию адреса памяти, полученного путем добавления базового адреса объекта и смещения для этого члена. Или это? Я новичок в этом, поэтому на данный момент я только угадываю и, вероятно, не хватает подробностей.

Например, я заметил, что если я реализую оператор + как void add(int * a, int * b, int * r); при работе с членами стека (и с использованием оператора &) код сборки идентичен тому, что создается оператором регулярного +, поэтому кажется, что указатели, которые, как известно, указывают на известные значения времени компиляции, оптимизированы для исключения дополнительных разыменований ( и копирование), а непрямые функции add() встроены как прямой доступ к объектам стека. Означает ли это, что компилятор "достаточно хорош", чтобы иметь возможность оптимизировать, например, аксессоры, реализованные с косвенностью из постоянных смещений значения из базового адреса объекта в стеке, как если бы с использованием доступа к членству в структуре для получения этого значения?

  • 0
    «сводится к разыменованию адреса памяти, полученного путем добавления базового адреса объекта и смещения для этого члена» Хмммм, да! И твой вопрос?
  • 0
    ^ Так больше ничего?
Показать ещё 1 комментарий
Теги:
pointers
indirection

1 ответ

0

Я не знаю, как вы внедрили тело функции, чтобы этот ответ мог быть полностью выключен :).

Если вы добавляете внутри своей функции r = a + b, код будет выглядеть одинаково, но не будет одинаковым.

для прототипа (int *, int *, int *) вы добавите указатели, что неверно. Чтобы получить целочисленное значение внутри вашей функции, тело должно быть:

*r = *a + *b ; 

ИЛИ

r[0] = a[0] + b[0];

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

для прототипа (int &, int &, int &) и тела

r = a + b;

компилятор включит эту функцию, так что да, сборка должна быть indentical.

  • 0
    Я думал, что само собой разумеется, функция add() реализована с использованием косвенного указателя, например, *r = *a + *b; , Компилятор генерирует идентичную сборку как оператор + только если функция встроена в статическом контексте, указывающем на известные объекты стека. Код идентичен инструкции для инструкции. Несмотря на то, что функция использует внутренние указатели, компилятор может сказать, что в скомпилированном контексте они указывают на объекты стека, поэтому компилятор обращается к тем, кто использует стек, а не тратит время на копирование указателей и косвенную оттуда.
  • 0
    Что ж, теория компилятора не является моим главным умением, но если вы используете косвенное указатель, возможно, компилятор выяснит, что вы передаете указатель, который затем отменяете ссылку, поэтому, чтобы избежать этого, он просто вставляет функцию и вместо используя дополнительные реестры для хранения значений указателей ( a, * b , * c), затем разыменовываем их, этот шаг пропускается, в результате получается код, идентичный + ... Попробуйте выполнить тот же тест с использованием более сложного контекста, где указатели переданные не получаются с использованием ссылок из предыдущего контекста, но являются целыми числами, выделенными в куче (что-то вроде * a = new int [1]).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню