At the 2016 Oulu ISO C++ Standards meeting, a proposal called Inline Variables was voted into C++17 by the standards committee.
In layman's terms, what are inline variables, how do they work and what are they useful for? How should inline variables be declared, defined and used?
Thus, an inline variable is one that is allowed to be defined in multiple files without violating the one definition rule. Inline global variables have external linkage by default. The linker will consolidate all inline definitions of a variable into a single variable definition (thus meeting the one definition rule).
An inline function is one for which the compiler copies the code from the function definition directly into the code of the calling function rather than creating a separate set of instructions in memory. This eliminates call-linkage overhead and can expose significant optimization opportunities.
In C++ (before C++17 version), we cannot initialize the value of static variables directly in the class. We have to define them outside of the class.
Example. In the following class declaration, the Account constructor is an inline function. The member functions GetBalance , Deposit , and Withdraw aren't specified as inline but can be implemented as inline functions. In the class declaration, the functions were declared without the inline keyword.
The first sentence of the proposal:
” The
inline
specifier can be applied to variables as well as to functions.
The ¹guaranteed effect of inline
as applied to a function, is to allow the function to be defined identically, with external linkage, in multiple translation units. For the in-practice that means defining the function in a header, that can be included in multiple translation units. The proposal extends this possibility to variables.
So, in practical terms the (now accepted) proposal allows you to use the inline
keyword to define an external linkage const
namespace scope variable, or any static
class data member, in a header file, so that the multiple definitions that result when that header is included in multiple translation units are OK with the linker – it just chooses one of them.
Up until and including C++14 the internal machinery for this has been there, in order to support static
variables in class templates, but there was no convenient way to use that machinery. One had to resort to tricks like
template< class Dummy >
struct Kath_
{
static std::string const hi;
};
template< class Dummy >
std::string const Kath_<Dummy>::hi = "Zzzzz...";
using Kath = Kath_<void>; // Allows you to write `Kath::hi`.
From C++17 and onwards I believe one can write just
struct Kath
{
static std::string const hi;
};
inline std::string const Kath::hi = "Zzzzz..."; // Simpler!
… in a header file.
The proposal includes the wording
” An inline static data member can be defined in the class definition and may specify a brace-or-equal-initializer. If the member is declared with the
constexpr
specifier, it may be redeclared in namespace scope with no initializer (this usage is deprecated; see D.X). Declarations of other static data members shall not specify a brace-or-equal-initializer
… which allows the above to be further simplified to just
struct Kath
{
static inline std::string const hi = "Zzzzz..."; // Simplest!
};
… as noted by T.C in a comment to this answer.
Also, the constexpr
specifier implies inline
for static data members as well as functions.
Notes:
¹ For a function inline
also has a hinting effect about optimization, that the compiler should prefer to replace calls of this function with direct substitution of the function's machine code. This hinting can be ignored.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With