static
Member Variables¶
Good Old C: extern
Global Variables¶
Declaration (and usage)
Hey compiler, please don’t care: the linker will bring that in. Not your business.
Hey linker, insist in bringing that in: find it in all the other compilation units. But only if it is “odr-used” (i.e., if it is referenced)
#include <stdio.h> extern int global; // <--- "extern" declaration int main(void) { printf("%d\n", global); return 0; }
Definition
Hey linker, if someone outside needs that, please happily offer it.
int global = 42; // <--- definition: allocates memory in .bss
ODR: One Definition Rule¶
A variable must be defined at most once
Can be left undefined if not used (⟶ odr-used)
Duplicate definition*
int global = 666;
double global = 42.7;
int main()
{
return 0;
}
Left undefined if unused*
extern int global;
int main()
{
return 0;
}
(A Litte) More Overengineered: Declaration In Header File¶
Declaration and definition always pairwise: header file and c file
Don’t place
extern
declaration directly at the user’s site⟶ Use a header file
#pragma once extern int global;
As above,
.c
file defines it (including.h
file only for type sanity checks)#include "extern-declaration.h" int global = 666;
Using entity (
main()
) include.h
to pull inextern
declaration, and toodr-use
the variable#include <stdio.h> #include "extern-declaration.h" int main(void) { printf("%d\n", global); return 0; }
Same Inside A Class: static
Member Variable¶
extern
declaration, only prettier#pragma once class Class { public: static int global; // <--- "extern" declaration };
Definition: same, only inside class
#include "class-good-old.h" int Class::global = 42; // <--- definition
Using entity, again. Not much different.
#include "class-good-old.h" #include <iostream> using namespace std; int main() { cout << Class::global << endl; return 0; }
Sideway: Definition In A Header File?¶
Definition of
static
class member not possibleC++ appears to enforce the ODR
class Class
{
public:
static int global = 666;
};
error: ISO C++ forbids in-class initialization of non-const static member ‘Class::global’
7 | static int global = 666; // <--- "extern" declaration
| ^~~~~~
static inline
Member Defnition (Since C++17)¶
Major trickery from C++ 17 onwards
ODR definition in class definition
⟶ no
.cpp
file anymore to satisfy ODR
Immune to multiple includers of the class
… which is the regular case
Burden placed upon the linker
#pragma once
class Class
{
public:
static inline int global = 42; // <--- **definition!!**
};