What is the difference between inline variables and inline static variables?

14.7k views Asked by At

I am a bit confused by the inline variable introduced by C++17. What are the differences between inline variable and inline static variable? Also will this be affected by scope?

inline T var_no_scope;
inline static T static_var_no_scope;

namespace scope {
  inline T var_scope;
  inline static T static_var_scope;
}

Any explanation will be appreciated!

6

There are 6 answers

0
AmirSalar On

The inline static variable can be defined in the class definition and may specify an initializer. It does not need an out-of-class definition:

struct X
{
    inline static int n = 1;
};

Inline variables eliminate the main obstacle to packaging C++ code as header-only libraries.

If you need to declare global variables that are shared between compilation units, declare them as inline variables in the header file.

Also will this be affected by scope?

Any of the following names declared at namespace scope have external linkage and also names declared without a namespace for external linkage including in multiple source files must be inline.

See this Example.

This link has valuable information about inline variables.

4
HolyBlackCat On

At namespace scope:

inline static seems to be equivalent to just static.

inline on variables only has effect when you define the same variable in several translation units. Since static restricts the variable to a single TU, you can't have more than one definition.

At class scope:

inline can only appear on static variables.

It has its normal effect, allowing you to initialize the variable directly in the header. Either:

struct A
{
    inline static int a = 42;
};

Or:

struct A
{
    static int a;
};

inline int A::a = 42;

At function scope:

inline is not allowed.

0
Szymon B On

Great answer about inline variables and why we want to use them can be found here. In short inline variable allows to have multiple definition of a variable (even across multiple files), that will result in one variable in memory. This allow constexpr global variables in header files.

header.h

namespace constants
{
    inline constexpr double P = 1.11;
}

Behavior is undefined when definitions have different values, but this shouldn't be a problem when multiplication of definitions occur only due to header file.

Others have pointed to a nice application in classes:

template<typename T>
struct C
{
    static inline constexpr int c = 10;
};

And then you can reference this variable anywhere, e.g. with: C<int>::c;

0
ptroen On

definition from c++ reference: citation: https://en.cppreference.com/w/cpp/language/inline

inline variable is defined as inline static keyword. Hence inline static vartype yourvariablename // is a inline variable.

Interesting note about inline "A function defined entirely inside a class/struct/union definition, whether it's a member function or a non-member friend function, is implicitly an inline function if it is attached to the global module"(C++ 20)

Ok from personal experience here's why inline static is a really really big thing:

  1. If all you need todo is initialize a static variable in a C++ file then you can remove the C++ file and use inline static initialization(but your code will require C++ 17 and up)

  2. Initializing static variables in pre C++ 17 classname templates is just overly verbose. You would have to do something like:

template class classname { static yourtype yourstaticvariable = yourvalue; // and you'll have to initialize it
};

template yourtype classname::yourstaticvariable = yourvalue;

OR with inline static you can just do:

template <class T>
class classname
{
    static yourtype yourstaticvariable = yourvalue; // initialized
}
  1. You can heavily exploit templates if you use inline static for initializing common things. Consider for instance the singleton where a inline static variable is perfect for tracking the instance and hence can be done in one file where before initializing the static variable would be painful. This becomes even more evident when you have multivariable templates.
  2. You need less C++ include files and less lib projects if you exploit inline static for single C++ header. This can heavily trim down files in a big project.

But there some caveats with inline static:

  1. You need C++ 17 and up
  2. You have to pay attention to issues of putting your initialization in a .h file(which you probably want to do if you initialize with inline static). Although this isn't necessarily a inline static issue but the decision to potentially moving everything to a header could lead to possible issues like namespace collisions, reusing macros or other things if you not careful with your order of inclusion.

But overall it's a fantastic feature. When in doubt initialize with inline static and break the I need a c++ file to initialize a static variable pattern.

0
Ja_cpp On

For me it becomes more interesting when it is a data members. In C++17 you can declare your static data members as inline. The advantage is that you don't have to allocate space for them in a source file. For example:

class A
{
// Omitted for brevity
static inline int b = 0;
};

So int A::b; can be removed from the source file.

1
Drew Dormann On

inline is applicable to variables only with static storage duration.

All of the variables in your example have namespace scope, giving them static storage duration. Declaring them inline has no net effect if they are static.

A variable inside a class, struct or union only has static storage duration if it is declared static. Those varibles must be static if they are to be inline.