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

Компилятор оптимизирует параметры функции, переданные по значению?

Предположим, что у меня есть функция, где параметр передается значением вместо const-reference. Кроме того, предположим, что внутри функции используется только значение, то есть функция не пытается ее модифицировать. В этом случае компилятор сможет определить, что он может передать значение по const-reference (по соображениям производительности) и сгенерировать код соответственно? Есть ли какой-нибудь компилятор, который делает это?

4b9b3361

Ответ 1

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

Кроме того, компилятор может делать все, что захочет (он должен только напоминать наблюдаемое поведение, если оно вообще не оптимизировалось).

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

Ответ 2

Только если функция не экспортируется, есть вероятность, что компилятор преобразует вызов по ссылке на вызов по значению (или наоборот).

В противном случае, из-за соглашения о вызове, функция должна сохранять семантический вызов по значению/ссылке.

Ответ 3

Мне не известны общие гарантии того, что это будет сделано, но если вызываемая функция встроена, тогда это позволит компилятору увидеть, что делается ненужная копия, и если уровень оптимизации высок достаточно, операция копирования будет устранена. GCC может сделать это как минимум.

Возможно, вам захочется подумать о том, имеет ли класс этого параметра конструктор копии или нет. Если это не так, то разница в производительности между передачей по значению и pass-by-const-ref, вероятно, является пренебрежимой.

С другой стороны, если у класса есть конструктор копий, который делает материал, то оптимизация, на которую вы надеетесь, вероятно, не произойдет, потому что компилятор не может удалить вызов конструктору - он не может знать, что побочные эффекты конструктор не важен для вас.

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

Ответ 4

При всех оптимизациях ответ обычно "может быть". Единственный способ проверить - проверить выходную сборку и посмотреть, что она на самом деле делает. Если стандарт позволяет это, независимо от того, действительно ли это происходит, до капризов компилятора. Вы не должны полагаться на это, потому что произвольное изменение в другом месте вашей кодовой базы может изменить эвристику, используемую оптимизатором, которая может заставить ее прекратить выполнение определенной оптимизации.

Играйте в безопасное место: введите код, как вы собираетесь - передайте по ссылке, если это то, что вы хотите. Однако, если вы пишете шаблонный код, который может работать с типами любого размера, выбор не так ясен. Лично я был бы связан с передачей по константной ссылке - компилятор мог также выполнять другую оптимизацию, где небольшой тип, который может вписываться в размер ссылки, передается по значению, а не по ссылке const. Но опять же, это может произойти, возможно, это не так.