it-swarm.com.ru

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

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

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

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

6
Joe Pineda

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

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

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

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

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

11
François Andrieux

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

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

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

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

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

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

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

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

1
chux

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

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

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

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

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

0
Handy999