Мой коллега увидел, что я ставлю 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 было доступно в каждой единице трансляции, где она вызывается и оно было в точности одинаковое.
Комментариев нет:
Отправить комментарий