Страницы

Поиск по вопросам

вторник, 16 апреля 2019 г.

Почему не рекомендуют ставить ключевое слово inline в реализации метода?

Мой коллега увидел, что я ставлю inline методам get и set и в объявлении метода и в реализации и сказал, что так делать не стоит, но аргументировать это не смог. Я тоже когда-то про такое слышал, но информации найти не смог. Я знаю, что компиляторы сейчас забивают даже на форсинлайны и обычный inline им вообще не указ. Но всё-таки, правда ли что inline ставить лучше только в объявлении метода и какие у этого есть объективные причины?


Ответ

Основное назначение слова inline: дать программисту инструмент определять функции так, чтобы у компилятора была возможность встроить их на этапе компиляции и не вызвать в дальнейшем ошибку компоновки.
Вторичное назначение: сообщение другим людям работающим над данным кодом, что автор надеется, что компилятор встроит эту функцию.
Кроме того это действительно является подсказкой компилятору встроить функцию (я сам сомневался в этом), которая на самом деле влияет на эвристики компилятора, например, увеличивая пороговые значения размера функции выше которых компилятор откажется её встраивать (смотри ссылку на статью в ответе @ixSci)
Пусть есть класс Foo с переменной a, к которой нужно обеспечить доступ; есть несколько вариантов, что можно сделать с getA
Определить прямо в классе.
class Foo { int a{0}; public: int Foo::getA () { return a; }
inline подразумевается, программист сразу понимает что к чему, компоновщик не жалуется о повторном определении. ИМХО — это предпочтительный вариант покуда реализация не занимает больше двух-трёх (пяти?) строк. Определить в хедере вне класса.
class Foo { int a{0}; public: int getA (); }
int Foo::getA () { return a;}
Это тот случай, когда использование слова inline обязательно и для чего оно и было введено, но где именно оно будет компилятору всё равно, вопрос исключительно стилистический. Распишу плюсы и минусы на мой взгляд (все они крайне эфемерны):
2.1. inline только в объявлении — назовём это «основным вариантом».
2.2. inline только в определении — относительно плохой вариант:
- При просмотре объявления программист будет рассчитывать, что компилятор не сможет (и не должен) встроить функцию, что для геттера вызывает ряд вопрсов и потенциально ложных предположений, например то что этот геттер не тривиальный и требует каких-то вычислений.
2.3. inline и в объявлении и в определении
+ При прочтении и объявления, и определения класса сразу видно, что функция встраиваемая. - Чревато скатыванием к предыдущему варианту, если кто-то удалит слово inline и не удосужится проверить. Определение в отдельном *.cpp
// foo.h class Foo { int a{0}; public: int getA (); }
// foo.cpp #include "foo.h" int Foo::getA () { return a;}
// main.cpp #include "foo.h" int main(void) { Foo foo; return foo.getA(); }
Если inline будет присутствовать в объявлении или определении, то это нарушение стандарта, который требует, чтобы определение функции объявленной как inline было доступно в каждой единице трансляции, где она вызывается и оно было в точности одинаковое.

Комментариев нет:

Отправить комментарий