О, человек, один из моих питомцев.
inline
больше похож на static
или extern
, чем директива, сообщающая компилятору встроить ваши функции. extern
, static
, inline
- это директивы привязки, используемые почти исключительно компоновщиком, а не компилятором.
Говорят, что inline
намекает компилятору, что вы считаете, что функция должна быть встроена. Это могло быть правдой в 1998 году, но десятилетие спустя компилятор не нуждается в таких подсказках. Не говоря уже о том, что люди обычно ошибаются, когда дело доходит до оптимизации кода, поэтому большинство компиляторов полностью игнорируют «подсказку».
static
- имя переменной/функции не могут быть использованы в других единицах компиляции. Linker должен убедиться, что он случайно не использует статически определенную переменную/функцию из другого модуля компиляции.
extern
- использовать это имя переменной/функции в этом модуле компиляции, но не жалуйтесь, если он не определен. Компонент будет сортировать его и убедиться, что весь код, который пытался использовать какой-либо символ extern, имеет свой адрес.
inline
- эта функция будет определена в нескольких единицах компиляции, не беспокойтесь об этом. Компилятор должен убедиться, что все единицы компиляции используют один экземпляр переменной/функции.
Примечание: Как правило, декларирование шаблоны inline
бессмысленно, так как они имеют рычажной семантику inline
уже. Однако, explicit
специализация и создание шаблонов require inline
для использования.
Конкретные ответы на вопросы:
-
Когда я должен написать ключевое слово 'встроенный' для функции/метода в C++?
Только если вы хотите, чтобы функция была определена в заголовке. Точнее, только когда определение функции может отображаться в нескольких единицах компиляции. Это хорошая идея, чтобы определить небольшие (как в одном лайнере) функции в файле заголовка, поскольку он дает компилятору больше информации для работы с оптимизацией кода. Это также увеличивает время компиляции.
-
Когда я не должен писать ключевое слово 'inline' для функции/метода в C++?
Не добавляйте встроенную линию только потому, что считаете, что ваш код будет работать быстрее, если компилятор включит его.
-
Когда компилятор не знает, когда нужно сделать функцию/метод 'inline'?
Как правило, компилятор сможет сделать это лучше вас.Однако компилятор не имеет возможности встроить код, если он не имеет определения функции. В максимально оптимизированном коде обычно используются все методы private
независимо от того, запрашиваете вы это или нет.
Для предотвращения встраивания в GCC используйте __attribute__((noinline))
, а в Visual Studio используйте __declspec(noinline)
.
-
Имеет ли значение, если приложение многопоточно, когда вы пишете 'inline' для функции/метода?
Многопоточность не влияет ни на что.
Если определить функцию в заголовке вы должны объявить его рядный. В противном случае вы получите ошибки компоновщика о нескольких определениях функции. –
@Martin: Если это не в определении класса, быть разборчивым. –
@David: быть лишним, это связано только с тем, что такие функции неявно отмечены 'inline' (9.3/2). –