C ++ "inline" - насколько он силен для GCC и Clang / LLVM? - PullRequest
14 голосов
/ 07 марта 2011

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

Мой вопрос: в коде, сгенерированном GCC и Clang / LLVM, ключевое слово "inline" имеет любой , указывающий, является ли функция встроенной? Если да, то в каких ситуациях? Или подсказка полностью игнорируется? Обратите внимание, что это не вопрос языка, это вопрос, относящийся к компилятору.

Ответы [ 3 ]

9 голосов
/ 07 марта 2011

[Предостережение: не гуру C ++ / GCC] Вы можете прочитать здесь inline .

Также это для GCC / C99.

Степень, в которой предложения, сделанные с помощью встроенного спецификатор функции эффективен (C99 6.7.4).

  • GCC не встроит никакие функции, если опция -fno-inline используется или, если используется -O0. В противном случае, GCC все еще может быть не в состоянии встроить функционировать по многим причинам; -Winline опция может быть использована для определения, если функция не была и почему нет.

Похоже, что если не используются настройки вашего компилятора (например, -fno-inline или -O0), компилятор поймет подсказку. Я не могу комментировать Clang / LLVM (или GCC действительно). '

Я рекомендую использовать -Winline, если это не вопрос кода, и вам нужно знать, что происходит.

7 голосов
/ 07 марта 2011

Интересное объяснение от gcc: встроенная функция работает так же быстро, как макрос :

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

Обратите внимание, что некоторые использования в функции определение может сделать его непригодным для встроенная замена. Среди этих использования: использование varargs, использование alloca, использование данных переменного размера типы (см. Переменная длина), использование вычисленный переход (см. Метки как значения), использование нелокальных goto и вложенных функции (см. Вложенные функции). Использование -Winline предупредит, когда встроенная функция не может быть подставить, и даст причину за неудачу.

В соответствии с требованиями ISO C ++, GCC считает, функции-члены, определенные в тело класса, помеченное как встроенное даже если они явно не объявлено с встроенным ключевым словом. Вы может переопределить это с -fno-умолчанию-рядный; см. Параметры управления диалектом C ++.

GCC не выполняет никаких функций, когда не оптимизировать, если вы не укажете Атрибут Always_inline для функция, как это:

 /* Prototype.  */
 inline void foo (const char) __attribute__((always_inline)); The remainder of this section is specific

встраивание в GNU C90.

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

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

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

4 голосов
/ 07 марта 2011

Насколько сильный намек зависит полностью от параметров компиляции, которые вы используете. У большинства компиляторов есть опции, чтобы не делать вставку, только встроить те, которые помечены как «встроенные», или использовать свое лучшее решение и игнорировать подсказки.

Последний, вероятно, работает лучше всего. : -)

...