Подтвердить что ты не робот

С++ передача аргументов по ссылке и указателю

в С++

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

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

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

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

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

заблаговременно

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

Ответ 3

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

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

Что касается стиля кода (помимо коммандов указателей и умных контролеров), я обычно использую ссылки, если адрес не может быть NULL по контракту функции и использовать указатели иначе.

Ответ 4

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