c ++ передача аргументов по ссылке и указателю - PullRequest
26 голосов
/ 18 июля 2011

в c ++

class bar
{
    int i;
    char b;
    float d;
};

void foo ( bar arg );
void foo ( bar &arg );
void foo ( bar *arg );

это пример класса / структуры и функций
у меня есть несколько Qs

  • в чем разница между 1-м и 2-м способом прохожденияаргумент в «асм», размер, скорость?
  • как аргументы передаются в функции foo в каждом случае (в случае указателя я знаю, что указатель помещается в стек)
  • при передаче аргументов, с точки зрения эффективности при (скоростиразмер, предпочтительность) что лучше?
  • каков синтаксис intel 'asm', который соответствует каждому из способов передачи аргументов?

Я знаю, что большинство говорят о «это не имеет значения для современных компиляторов и процессоров», но что, если мы говорим о старых процессорах или компиляторах?

заранее спасибо

Ответы [ 5 ]

22 голосов
/ 18 июля 2011

Указатель и эталонные методы должны быть вполне сопоставимы (как по скорости, использованию памяти и генерируемому коду).

Передача класса напрямую вынуждает компилятор дублировать память и помещать копию barобъект в стеке.Что еще хуже, в C ++ есть все виды неприятных битов (конструктор копирования по умолчанию и еще много чего), связанных с этим.

В CI всегда используются (возможно, const) указатели.В C ++ вы, вероятно, должны использовать ссылки.

3 голосов
/ 18 июля 2011

Любой разумный способ передачи по ссылке, вероятно, приведет к коду, включающему адреса объектов.Однако главная проблема заключается в том, что использование ссылок является более идиоматическим C ++ и должно быть предпочтительным стилем;вы действительно не должны видеть много сырых указателей в своем собственном коде.

Также обратите внимание, что передача по значению и по ссылке принципиально отличается в том смысле, что передача по ссылке позволяет вызываемому пользователю изменять аргумент.Во всяком случае, вы должны сравнивать f(bar) с f(const bar &).

2 голосов
/ 18 июля 2011

Указатели и ссылки различаются синтаксически и обычно идентичны во время выполнения и генерации кода. Что касается старых компиляторов ... Я знал одну ошибку в DOS-компиляторе Borland 3 C ++: он кэшировал значение int (передаваемое по ссылке) в регистр, изменял его и не изменял исходное значение в памяти. При передаче по указателю эквивалентный код работал как ожидалось.

Однако я не думаю, что какой-либо современный компилятор может делать такие странные вещи (а Borland 5 исправил эту проблему)

Что касается стиля кода (кроме компромиссов между указателями и умными указателями), я обычно использую ссылки, если адрес не может быть НЕДЕЙСТВИТЕЛЕН по контракту функции, и иначе использую указатели.

0 голосов
/ 16 ноября 2018

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

0 голосов
/ 18 июля 2011

Функция foo может изменять arg в случаях 2 и 3. В первых случаях компилятор может оптимизировать создание копии, поэтому очень сложно сравнивать использование процессора и памяти.

...