Может ли очень короткая функция стать встроенной, даже если она не была явно определена как встроенная? - PullRequest
0 голосов
/ 27 ноября 2018

Я заранее знаю, что при написании программы на C или C ++, даже если я объявляю функцию как «встроенную», компилятор может игнорировать это и принимать решение не расширять ее при каждом (или любом) вызове.

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

Два других подвопроса: это поведение определено где-то в ANSIстандарты?В этом отношении C отличается от C ++ или ведет себя одинаково?

Ответы [ 4 ]

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

Что касается отношения между C и C ++, встроенный спецификатор обрабатывается по-разному в каждом языке.

  • В C ++: встроенные функции (и функции, подобные сущностям, и переменные (начиная с C ++ 17)), которые ранее не были объявлены с внутренней связью, будут иметь внешнюю связь и будут видны из других модулей компиляции.Поскольку встроенные функции (обычно) находятся в заголовочных файлах, это означает, что одна и та же функция будет иметь повторяющиеся определения для разных блоков компиляции (это будет нарушением правила одного определения , но inline делает егоюридическое).В конце процесса сборки (при связывании исполняемого файла или разделяемой библиотеки) встроенные определения одного и того же объекта объединяются.Неофициально, C ++ inline означает: «может быть несколько идентичных определений какой-либо функции в нескольких исходных файлах, но я хочу, чтобы они заканчивались как уникальное определение».
  • В C: если externне указано явно, то определение встроенной функции не видно из других единиц перевода, разные единицы перевода могут иметь разные определения со спецификатором inline для того же имени функции.Кроме того, может существовать (самое большее) одно определение для имени функции, которое является одновременно inline и extern, и это квалифицирует эту функцию как внешнюю видимую функцию (то есть выбирается, когда применяется адрес &оператор к имени функции).Правило определения One из C и его связь с extern и inline несколько отличается от C ++.
0 голосов
/ 27 ноября 2018

Когда речь идет о стандарте, ключевое слово inline имеет ничего , связанного с встраиванием.

Правила (на с ++) в основном:

  • Функция, которая не объявлена ​​inline, может быть определена только в одном объединении перевода.Его по-прежнему необходимо обрабатывать в каждой единице перевода, где он используется.
  • Функция, которая объявлена ​​inline, должна быть определена в каждой единице перевода, где она используется в odr (ord-use означает, что для вызовафункция или взять указатель, ...).

Таким образом, в стандартных настройках проекта почти всегда правильно следовать следующим двум правилам.Функции, которые определены в заголовочном файле: всегда , которые должны быть объявлены inline.Функции, определенные в * .cpp-файле, никогда не объявляются inline.

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

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

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

Ограничение:
КогдаВ коде используется указатель на функцию, тогда функция должна существовать без подстановки.

Ограничение:
Когда функция видна за пределами локального файла .c (не static), это предотвращает упрощениевстроенный код.

Не ограничение:
Длина функции не является абсолютным, хотя и практическим ограничением.

Я работал со встроенным процессором, который обычно встроен static функции.(Данный код не использует указатель на них.)

Полезность ключевого слова inline не влияет на способность компилятора встроить функцию.

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

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

От https://en.cppreference.com/w/cpp/language/inline:

Поскольку это значение ключевого слова inline не является обязательным, компиляторы могут использовать встроенную подстановку для любой функции, которая не помечена как inline , и могут генерировать вызовы функций.для любой функции, помеченной как встроенная.Эти варианты оптимизации не изменяют правила, касающиеся нескольких определений и общей статики, перечисленных выше.

Редактировать: Поскольку вы также запросили C, с https://en.cppreference.com/w/c/language/inline:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...