В 17 стандарте есть новая фича: inline переменные. Но я не совсем понимаю, а в чем разница между inline и static переменной?
До С++17 было два основных способа объявить/определить глобальную переменную, которая используется в нескольких единицах трансляции:
//my.h
extern int foo;
static int bar = 0;
//my.cpp
int foo = 0;
Переменная foo — обычная переменная со внешним связыванием, объявлена в хедере и обределена/инициализирутся точно в одной единице трансляции.
Переменная bar — статическая переменная, объявлена и инициализируется в хедере. При этом каждая единица трансляции работает со своей копией объекта. Зачастую это ошибка.
В c++17 достаточно сделать:
//my.h
inline int baz = 0;
По большей части это просто синтаксический сахар: baz, объявлена и инициализируется в хедере, как и в случае static, но все единицы трансляции работают с одним и тем же объектом, как в случае с extern, а компилятор сам выберет модуль, куда пристроит символ (по аналогии с inline-функциями). Оптимизационного потенциала это несёт крайне мало т.к. почти все его перспективные применения уже покрыты constexpr.
Не-const переменная, объявленная на уровне пространства имен без слова static имеет внешнее связывание, т.е. существует в единственном экземпляре во всей программе.
Переменная, объявленная на уровне пространства имен со словом static имеет внутреннее связывание, т.е. существует как отдельная переменная в каждой единице трансляции, в которой объявлена.
Так было всегда.
inline никак не меняет этих свойств. inline лишь позволяет нам делать множественные определения переменных с внешним связыванием в разных единицах трансляции, не вызывая при этом нарушения ODR (полностью аналогично тому, как inline влияет на функции). Без inline нам придется идти по традиционному пути: помещать в заголовочные файлы extern-объявления глобальных переменных, а определения с инициализаторами прятать в файлах реализации. Это более громоздко и это приводит к тому, что инициализатор глобальной переменной виден лишь в одной единице трансляции. С inline все сводится к одному-единственному объявлению-определению, которое можно делать в заголовочном файле и которое целиком (т.е. вместе с инициализатором) видно везде.
Это в частности означает, что для переменных комбинация inline static является избыточной: можно просто написать static с тем же эффектом.
Продвижение своими сайтами как стратегия роста и независимости