I am trying to design header only library, which unfortunately needs to have global static variable (either in class or in namespace).
Is there any way or preferred solution to have global static variable while maintaining header only design?
The code is here
There are a couple of options. The first thing that came to my mind was that C++ allows static data members of class templates to be defined in more than one translation unit:
template<class T>
struct dummy {
static int my_global;
};
template<class T>
int dummy<T>::my_global;
inline int& my_global() {return dummy<void>::my_global;}
The linker will merge multiple definitions into one. But inline alone is also able to help here and this solution is much simpler:
inline int& my_global() {
static int g = 24;
return g;
}
You can put this inline function into a header file and include it into many translation units. C++ guarantees that the reference returned by this inline function will always refer to the same object. Make sure that the function has external linkage.
Related
There are two implications of using the inline keyword(§ 7.1.3/4):
It hints the compiler that substitution of function body at the point of call is preferable over the usual function call mechanism.
Even if the inline substitution is omitted, the other rules(especially w.r.t One Definition Rule) for inline are followed.
Usually any mainstream compiler will substitute function body at the point of call if needed, so marking function inline merely for #1 is not really needed.
Further w.r.t #2, As I understand when you declare a function as static inline function,
The static keyword on the function forces the inline function to have an internal linkage(inline functions have external linkage) Each instance of such a function is treated as a separate function(address of each function is different) and each instance of these functions have their own copies of static local variables & string literals(an inline function has only one copy of these)
Thus such a function acts like any other static function and the keyword inline has no importance anymore, it becomes redundant.
So, Practically marking a function static and inline both has no use at all. Either it should be static(not most preferred) or inline(most preferred),
So, Is using static and inline together on a function practically useless?
Your analysis is correct, but doesn't necessarily imply uselessness. Even if most compilers do automatically inline functions (reason #1), it's best to declare inline just to describe intent.
Disregarding interaction with inline, static functions should be used sparingly. The static modifier at namespace scope was formerly deprecated in favor of unnamed namespaces (C++03 §D.2). For some obscure reason that I can't recall it was removed from deprecation in C++11 but you should seldom need it.
So, Practically marking a function static and inline both has no use at all. Either it should be static(not most preferred) or inline(most preferred),
There's no notion of preference. static implies that different functions with the same signature may exist in different .cpp files (translation units). inline without static means that it's OK for different translation units to define the same function with identical definitions.
What is preferred is to use an unnamed namespace instead of static:
namespace {
inline void better(); // give the function a unique name
}
static inline void worse(); // kludge the linker to allowing duplicates
Static and inline are orthogonal (independent). Static means the function should not be visible outside of the translation unit, inline is a hint to the compiler the programmer would like to have this function inlined. Those two are not related.
Using static inline makes sense when the inlined function is not used outside of the translation unit. By using it you can prevent a situation of accidental violation of ODR rule by naming another inlined function in another tranlation unit with the same name.
Example:
source1.cpp:
inline int Foo()
{
return 1;
}
int Bar1()
{
return Foo();
}
source2.cpp:
inline int Foo()
{
return 2;
}
int Bar2()
{
return Foo();
}
Without using static on Foo (or without using an anonymous namespace, which is preferred way by most C++ programmers), this example violates ODR and the results are undefined. You can test with Visual Studio the result of Bar1/Bar2 will depend on compiler settings - in Debug configuration both Bar1 and Bar2 will return the same value (inlining not used, one implementation selected randomly by the linker), in Release configuration each of them will return the intended value.
I may not be completely right about this, but as far as I know declaring a function static inline is the only way to make (or allow) the compiler to generate a machine code where the function really is not defined in the compiled code at all, and all you have is a direct substitution of the function call into a sequence of instructions, like it were just a regular procedure body, with no trace in the machine code of a procedure call relative to that function definition from the source code.
That is, only with static inline you can really substitute the use of a macro, inline by itself is not enough.
A simple Google search for "static inline" will show you compiler documentation pages that talk about it. I guess this should be enough to answer your question, and say, "no, it is not practically useless". Here is one example of a site discussing the use of inline, and specifically of static inline http://www.greenend.org.uk/rjk/tech/inline.html
If you talk about free functions (namespace scope), then your assumption is correct. static inline functions indeed don't have much value. So static inline is simply a static function, which automatically satisfies ODR and inline is redundant for ODR purpose.
However when we talk about member methods (class scope), the static inline function does have the value.
Once you declare a class method as inline, it's full body has to be visible to all translation units which includes that class.
Remember that static keyword has a different meaning when it comes for a class.
Edit: As you may know that static function inside a class doesn't have internal linkage, in other words a class cannot have different copies of its static method depending on the translation (.cpp) units.
But a free static function at namespace/global scope does have different copies per every translation unit.
e.g.
// file.h
static void foo () {}
struct A {
static void foo () {}
};
// file1.cpp
#include"file.h"
void x1 ()
{
foo(); // different function exclusive to file1.cpp
A::foo(); // same function
}
// file2.cpp
#include"file.h"
void x2 ()
{
foo(); // different function exclusive to file2.cpp
A::foo(); // same function
}
I just read a man page for gcc and it specifically states the use of static inline with a compiler flag. In the case of the flag, it inlines the function and if it is also static and is inlined in every instance that it is called, then it gets rid of the function definition which will never be used in the created object file, thereby reducing the size of the generated code by that little bit.
I just wrote a class with some static data members, but now I am getting errors about "undefined references". Why doesn't this work? What am I doing wrong?
_(Note: This is meant to be an entry to [Stack Overflow's C++ FAQ](https://stackoverflow.com/questions/tagged/c++-faq). If you want to critique the idea of providing an FAQ in this form, then [the posting on meta that started all this](https://meta.stackexchange.com/questions/68647/setting-up-a-faq-for-the-c-tag) would be the place to do that. Answers to that question are monitored in the [C++ chatroom](https://chat.stackoverflow.com/rooms/10/c-lounge), where the FAQ idea started out in the first place, so your answer is very likely to get read by those who came up with the idea.)_
To understand this, you should have a good understanding of compiling and linking, and the differences between declarations and definitions.
Consider the following class:
//In header file
class Example {
static bool exampleStaticMember;
};
Here, exampleStaticMember is declared but not defined. This means that if exampleStaticMember is used in a way that means that it must have an address then there must be a separate definition for it. In general, no declaration of a static data member in a class definition is a definition of that member.
The required declaration is usually put in the cpp file which contains the other definitions for the members of the class. It must be in the same namespace as the class definition. The definition typically looks like:
//In source file:
//This may optionally have an initialiser (eg "= true")
bool Example::exampleStaticMember;
The definition can be put in any cpp file, but it should not be put in the header with the class, because that would be likely to break the One Definition Rule.
As a special case, if the static member variable is an const integral or enumeration type then it can have an initialiser in the class definition:
//In header file
class Example {
static const int initialised = 15;
};
In this case, the definition in the cpp file is still required, but it is not allowed to have an initialiser:
//In source file
//Note: no initialiser!
const int Example::initialised;
Static members that have been initialised like this can be used in constant expressions.
Templates
For a static data member of a template, things are slightly different. The static member should be defined in the header along with the rest of the class:
//In header file
template<typename T>
class Example {
static int exampleInt;
static T exampleT;
}
template<typename T> int Example<T>::exampleInt;
template<typename T> T Example<T>::exampleT;
This works because there is a specific exception to the One Definition Rule for static data members of class templates.
Other uses of static
When the static keyword is applied to functions and objects that are not in a class scope it can take on a very different meaning.
When applied to objects in a function scope, it declares an object that is initialised in the first execution of the function and that subsequently keeps its value between function calls.
When applied to objects or functions at namespace scope (outside of any class or function definition), it declares objects or functions with internal linkage. This usage is deprecated for objects, as the unnamed-namespace provides a better alternative.
You have to instantiate static members defined in a header in a .cpp file. For example:
// foo.h
class foo {
static int X;
};
// foo.cpp
#include "foo.h"
int foo::X = 0;
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!
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.
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.
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.
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;
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.
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:
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)
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
}
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.
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:
You need C++ 17 and up
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.
Given is a class with a static member.
class BaseClass
{
public:
static std::string bstring;
};
String has obviously to be default-initialized outside of the class.
std::string BaseClass::bstring {"."};
If I include the above line in the header along with the class, I get a symbol multiply defined error. It has to be defined in a separate cpp file, even with include guards or pragma once.
Isn't there a way to define it in the header?
You can't define a static member variable more than once. If you put variable definitions into a header, it is going to be defined in each translation unit where the header is included. Since the include guards are only affecting the compilation of one translation unit, they won't help, either.
However, you can define static member functions! Now, at first sight that may not look as if it could help except, of course, that function can have local static variable and returning a reference to one of these behaves nearly like a static member variable:
static std::string& bstring() { static std::string rc{"."}; return rc; }
The local static variable will be initialized the first time this function is called. That is, the construction is delayed until the function is accessed the first time. Of course, if you use this function to initialize other global objects it may also make sure that the object is constructed in time. If you use multiple threads this may look like a potential data race but it isn't (unless you use C++03): the initialization of the function local static variable is thread-safe.
In C++17 you can use inline variables, which you can use even outside classes.
The inline specifier, when used in a decl-specifier-seq of a variable with static storage duration (static class member or namespace-scope variable), declares the variable to be an inline variable.
A static member variable (but not a namespace-scope variable) declared constexpr is implicitly an inline variable.⁽¹⁾
For example:
class Someclass {
public:
inline static int someVar = 1;
};
Or,
namespace SomeNamespace {
inline static int someVar = 1;
}
⁽¹⁾ https://en.cppreference.com/w/cpp/language/inline
Regarding
” Isn't there a way to define [the static data member] in the header?
Yes there is.
template< class Dummy >
struct BaseClass_statics
{
static std::string bstring;
};
template< class Dummy >
std::string BaseClass_statics<Dummy>::bstring = ".";
class BaseClass
: public BaseClass_statics<void>
{};
An alternative is to use a function, as Dietmar suggested. Essentially that is a Meyers' singleton (google it).
Edit: Also, since this answer was posted we've got the inline object proposal, which I think is accepted for C++17.
Anyway, think twice about the design here. Globals variables are Evil™. This is essentially a global.
To keep the definition of a static value with the declaration in C++11
a nested static structure can be used. In this case the static member
is a structure and has to be defined in a .cpp file, but the values
are in the header.
class BaseClass
{
public:
static struct _Static {
std::string bstring {"."};
} global;
};
Instead of initializing individual members the whole static structure is initialized:
BaseClass::_Static BaseClass::global;
The values are accessed with
BaseClass::global.bstring;
Note that this solution still suffers from the problem of the order of
initialization of the static variables. When a static value is used to
initialize another static variable, the first may not be initialized,
yet.
// file.h
class File {
public:
static struct _Extensions {
const std::string h{ ".h" };
const std::string hpp{ ".hpp" };
const std::string c{ ".c" };
const std::string cpp{ ".cpp" };
} extension;
};
// file.cpp
File::_Extensions File::extension;
// module.cpp
static std::set<std::string> headers{ File::extension.h, File::extension.hpp };
In this case the static variable headers will contain either { "" }
or { ".h", ".hpp" }, depending on the order of initialization created by the linker.
§3.2.6 and the following paragraphs from the current c++ 17 draft (n4296) define the rules when more than one definition can be present in different translation units:
There can be more than one definition of a class type (Clause 9), enumeration type (7.2), inline function with
external linkage (7.1.2), class template (Clause 14), non-static function template (14.5.6), static data member
of a class template (14.5.1.3), member function of a class template (14.5.1.1), or template specialization for
which some template parameters are not specified (14.7, 14.5.5) in a program provided that each definition
appears in a different translation unit, and provided the definitions satisfy the following requirements. Given
such an entity named D defined in more than one translation unit, then [...]
Obviously definitions of static data members of class type are not considered to appear in multiple translations units. Thus, according to the standard, it is not allowed.
The suggested answers from Cheers and hth. - Alf and Dietmar are more kind of a "hack", exploiting that definitions of
static data member of a class template (14.5.1.3)
and
inline function with external linkage (7.1.2)
are allowed in multiple TU ( FYI: static functions defined inside a class definition have external linkage and are implicitly defined as inline ) .
No, it can't be done in a header - at least not if the header is included more than once in your source-files, which appears to be the case, or you wouldn't get an error like that. Just stick it in one of the .cpp files and be done with it.
UPDATE: My answer below explains why this cannot be done in the way suggested by the question. There are at least two answers circumventing this; they may or may not solve the problem.
The bstring static member has to be linked to a specific memory address. For this to happen, it has to appear in a single object file, therefore it has to appear in a single cpp file. Unless you're playing with #ifdef's to make sure this happens, what you want cannot be done in the header file, as your header file may be included by more than one cpp files.
I'd like to package a library I'm working on as a header-only library to make it easier for clients to use. (It's small and there's really no reason to put it into a separate translation unit) However, I cannot simply put my code in headers because this violates C++'s one definition rule. (Assuming that the library header is included in multiple translation units of a client project)
How does one modify a library to make it header-only?
You can use the inline keyword:
// header.hpp (included into multiple translation units)
void foo_bad() {} // multiple definitions, one in every translation unit :(
inline void foo_good() {} // ok :)
inline allows the linker to simply pick one definition and discard the rest.
(As such, if those definitions don't actually match, you get a good dose of undefined behavior...!)
As an aside, member functions defined within a class-type, are implicitly marked inline:
struct myclass
{
void i_am_inline_implicitly()
{
// because my definition is here
}
void but_i_am_not();
void neither_am_i();
};
inline void myclass::but_i_am_not()
{
// but that doesn't mean my definition cannot be explicitly inline
}
void myclass::neither_am_i()
{
// but in this case, no inline for me :(
}
Use header guards as Liz suggests and don't forget to put "inline" before your function methods.
ie
#ifndef MY_HEADER_H_
#define MY_HEADER_H_
inline RetType FunctionName( ParamType1 param1, ParamType2 param2 )
{
// Function body
return retType;
}
#endif
Also, I think you'll need to avoid any use of global variables or static variables in your header-only-library code.
Use header guards for the parts that compile in one place.