What makes a static variable initialize only once? - c++

I noticed that if you initialize a static variable in C++ in code, the initialization only runs the first time you run the function.
That is cool, but how is that implemented? Does it translate to some kind of twisted if statement? (if given a value, then ..)
void go( int x )
{
static int j = x ;
cout << ++j << endl ; // see 6, 7, 8
}
int main()
{
go( 5 ) ;
go( 5 ) ;
go( 5 ) ;
}

Yes, it does normally translate into an implicit if statement with an internal boolean flag. So, in the most basic implementation your declaration normally translates into something like
void go( int x ) {
static int j;
static bool j_initialized;
if (!j_initialized) {
j = x;
j_initialized = true;
}
...
}
On top of that, if your static object has a non-trivial destructor, the language has to obey another rule: such static objects have to be destructed in the reverse order of their construction. Since the construction order is only known at run-time, the destruction order becomes defined at run-time as well. So, every time you construct a local static object with non-trivial destructor, the program has to register it in some kind of linear container, which it will later use to destruct these objects in proper order.
Needless to say, the actual details depend on implementation.
It is worth adding that when it comes to static objects of "primitive" types (like int in your example) initialized with compile-time constants, the compiler is free to initialize that object at startup. You will never notice the difference. However, if you take a more complicated example with a "non-primitive" object
void go( int x ) {
static std::string s = "Hello World!";
...
then the above approach with if is what you should expect to find in the generated code even when the object is initialized with a compile-time constant.
In your case the initializer is not known at compile time, which means that the compiler has to delay the initialization and use that implicit if.

Yes, the compiler usually generates a hidden boolean "has this been initialized?" flag and an if that runs every time the function is executed.
There is more reading material here: How is static variable initialization implemented by the compiler?

While it is indeed "some kind of twisted if", the twist may be more than you imagined...
ZoogieZork's comment on AndreyT's answer touches on an important aspect: the initialisation of static local variables - on some compilers including GCC - is by default thread safe (a compiler command-line option can disable it). Consequently, it's using some inter-thread synchronisation mechanism (a mutex or atomic operation of some kind) which can be relatively slow. If you wouldn't be comfortable - performance wise - with explicit use of such an operation in your function, then you should consider whether there's a lower-impact alternative to the lazy initialisation of the variable (i.e. explicitly construct it in a threadsafe way yourself somewhere just once). Very few functions are so performance sensitive that this matters though - don't let it spoil your day, or make your code more complicated, unless your programs too slow and your profiler's fingering that area.

They are initialized only once because that's what the C++ standard mandates. How this happens is entirely up to compiler vendors. In my experience, a local hidden flag is generated and used by the compiler.

Related

Do static and dynamic initialization only apply to non-local variables?

Here is the code:
int factorial(int n)
{
if ( n < 0 ) return -1; //indicates input error
else if ( n == 0 ) return 1;
else return n * factorial(n-1);
}
int const a = 10 ; //static initialization
//10 is known at compile time. Its 10!
int const b = factorial(8); //dynamic initialization
//factorial(8) isn't known at compile time,
//rather it's computed at runtime.
(stolen from here)
So it makes sense to me why b is dynamically initialized and a is statically initialized.
But what if a and b had automatic storage duration(maybe they had been initialized in main()), could you then still call their initialization either static or dynamic? Because, to me, they sound like a more general name for initialization than for example Copy initialization.
Also, I have read this and can anybody tell me why they have not directly explained what static and dynamic initialization are? I mean, it looks like that they only have explained in what situations they happen, but maybe there is a reason why?
cppreference states the initializer may invoke (some intializations, like value initialization etc.), but later in the article, they mention static and dynamic initialization as if those two were more general names for some initializations. This could sound confusing, but here I have illustrated what I understand:
(not the most beautiful thing)
Static and dynamic initialization describe the process of loading a binary and getting to the point when main is ready to run.
static initialization describes the information the compiler can work out at compile time, and allows for fixed values to be stored in the binary so at the point when the binary is loaded by the operating system, it has the correct value.
dynamic initialization describes the code which is inserted by the compiler before main runs, which initializes the information which the compiler was unable to calculate. That may be because it involves code directly, or that it refers to information which was not visible to the compiler at compile time.
But what if a and b had automatic storage duration
The simple case when a is an automatic variable of limited scope.
int a = 12;
This could not be statically initialized, because the compiler will not know where to initialize a, as it would be different each time, and on each thread which called it.
The compiler will be able to initialize a with something like.
mov (_addr_of_a), 12
As _addr_of_a is unknown until runtime, and the value 12 is embedded in the code, a case for statically initializing it would not be done.
More complex cases ...
int a[] = { /* some integer values */ };
This is possibly going to be implemented by the compiler as a mixture of static and dynamic code as below.
static int a_init = { /* some integer values */ };
memcpy( a, a_init, length_in_bytes_of_a );
So some cases there will be "leakage" from static initialization into runtime behaviour.
Dynamic behavior is more problematic - it assumes that a function which does not normally expose its implementation, has both a slow execution time, and is a constexpr to give value to the caching at start of the result. I have not seen this optimization occur.
Static and dynamic initialization are technical terms which describe the process of creating a running program. Similar patterns may exist for local variables, but they would not fall into the technical definition of static and dynamic initialization.

Crazy talk (paranoid about initialization)

I learned long ago that the only reliable way for a static member of be initialized for sure is to do in a function. Now, what I'm about to do is to start returning static data by non-const reference and I need someone to stop me.
function int& dataSlot()
{
static int dataMember = 0;
return dataMember;
}
To my knowledge this is the only way to ensure that the static member is initlized to zero. However, it creates obscure code like this:
dataSlot() = 7; // perfectly normal?
The other way is to put the definition in a translation unit and keep the stuff out of the header file. I have nothing against that per se but I have no idea what the standard says regard when and under what circumstances that is safe.
The absolute last thing I wanna end up doing is accidently accessing uninitialized data and losing control of my program.
(With the usual cautions against indiscriminate use of globals...) Just declare the variable at global scope. It is guaranteed to be zero-initialized before any code runs.
You have to be more cunning when it comes to types with non-trivial constructors, but ints will work fine as globals.
Returning a non-const reference in itself is fairly harmless, for example it's what vector::at() does, or vector::iterator::operator*.
If you don't like the syntax dataSlot() = 7;, you could define:
void setglobal(int i) {
dataSlot() = i;
}
int getglobal() {
return dataSlot();
}
Or you could define:
int *dataSlot() {
static int dataMember = 0;
return &dataMember;
}
*dataSlot() = 7; // better than dataSlot() = 7?
std::cout << *dataSlot(); // worse than std::cout << dataSlot()?
If you want someone to stop you, they need more information in order to propose an alternative to your use of mutable global state!
It is called Meyers singletor, and it is almost perfectly safe.
You have to take care that the object is created when the function dataSlot() is called, but it is going to be destroyed when the program exists (somewhere when global variables are destructed), therefore you have to take special care. Using this function in destructors is specially dangerous and might cause random crashes.
I learned long ago that the only reliable way for a static member of be initialized for sure is to do in a function.
No, it isn't. The standard guarantees that:
All objects with static storage (both block and file or class-static scope) with trivial constructors are initialized before any code runs. Any code of the program at all.
All objects with file/global/class-static scope and non-trivial constructos are than initialized before the main function is called. It is guaranteed that if objects A and B are defined in the same translation unit and A is defined before B, than A is initialized before B. However order of construction of objects defined in different translation units is unspecified and will often differ between compilations.
Any block-static objects are initialized when their declaration is reached for the first time. Since C++03 standard does not have any support for threads, this is NOT thread-safe!
All objects with static storage (both block and file/global/class-static scoped) are destroyed in the reverse order of their constructors completing after the main() function exits or the application terminates using exit() system call.
Neither of the methods is usable and reliable in all cases!
Now, what I'm about to do is to start returning static data by non-const reference and I need someone to stop me.
Nobody is going to stop you. It's legal and perfectly reasonable thing to do. But make sure you don't fall in the threads trap.
E.g. any reasonable unit-test library for C++ automatically registers all test cases. It does it by having something like:
std::vector<TestCase *> &testCaseList() {
static std::vector<TestCase *> test_cases;
return test_cases;
}
TestCase::TestCase() {
...
testCaseList().push_back(this);
}
Because that's the one of only two ways to do it. The other is:
TestCase *firstTest = NULL;
class TestCase {
...
TestCase *nextTest;
}
TestCase::TestCase() {
...
nextTest = firstTest;
firstTest = this;
}
this time using the fact that firstTest has trivial constructor and therefore will be initialized before any of the TestCases that have non-trivial one.
dataSlot() = 7; // perfectly normal?
Yes. But if you really want, you can do either:
The old C thing of
#define dataSlot _dataSlot()
in a way the errno "variable" is usually defined,
Or you can wrap it in a struct like
class dataSlot {
Type &getSlot() {
static Type slot;
return slot;
}
operator const Type &() { return getSlot(); }
operator=(Type &newValue) { getSlot() = newValue; }
};
(the disadvantage here is that compiler won't look for Type's method if you try to invoke them on dataSlot directly; that's why it needs the operator=)
You could make yourself 2 functions, dataslot() and set_dataslot() which are wrappers round the actual dataslot, a bit like this:
int &_dataslot() { static int val = 0; return val; }
int dataslot() { return _dataslot(); }
void set_dataslot(int n) { _dataslot() = n; }
You probably wouldn't want to inline that lot in a header, but I've found some C++ implementations do rather badly if you try that sort of thing anyway.

What run-time costs are there to initializing a static with a variable value?

In C++, what is the expected runtime cost in a reasonable compiler of initializing a static variable with a variable value as opposed to a constant value?
For example consider this code:
bool foo();
bool baz1() {
const bool value = foo();
static bool alternate1 = value;
static bool alternate2 = false;
// Do something.
return alternate1;
}
What is the expected run-time cost difference between alternate1 and alternate2?
Initialisation from a compile-time constant (alternate 2) will most likely happen during program startup, with no cost each time the function is called.
Thread-safe initialisation of a local static variable will cause the compiler to generate something like this pseudocode:
static bool alternate1;
static bool __initialised = false;
static __lock_type __lock;
if (!__initialised) {
acquire(__lock);
if (!__initialised) {
alternate1 = value;
__initialised = true;
}
release(__lock);
}
So there is likely to be a test of a flag each time the function is called (perhaps involving a memory barrier or other synchronisation primitive), and a further cost of acquiring and releasing a lock the first time.
Note that in your code, foo() is called every time, whether or not the variable is initialised yet. It would only be called the first time, if you changed the initialisation to
static bool alternate1 = foo();
The details are implementation-dependent of course; this is based on my observations of the code produced by GCC.
static variables are initialized at the start of your program, which means the init will only occur once. The cost for just a boolean is very low, and for your alternate1 will be the cost of executing foo(), which in your example is not much, since it's just an empty function.
To generalize, the cost will be the maximum cost of either initializing your basic type (int, float, etc) or the cost of initializing (running the ctor) of any user defined type/library defined type. Any static that is initialized with a function, then the max will be the cost of the function being executed.
It appears that your question is not about a static variable in general, but rather about a static variable declared inside a function.
The additional run-time costs of initializing such variable from a run-time value stem from several sources
Such variable should be initialized only once, when the control passes over its declaration the very first time (if ever). In order to achieve that an additional boolean variable/flag is allocated for each such variable and checked every time the control passes over the declaration. If the flag says that the variable is not initialized yet, it gets initialized.
For those static variables has non-trivial destructors, the language has to guarantee that their destruction order at program termination is the reverse of their construction order. Since the construction order determined at run-time, the program has to prepare a run-time structure to schedule the future destructions. This is also done as part of step 1 for variables with non-trivial destructors: they are registered in a "list" of constructed objects in order of their construction. The "list" is typically implemented as a pre-allocated array (since its maximum size is known at compile time).
In multithreaded configurations the above steps might/will be accompanied with additional locking/unlocking steps.
Since these are all "household" expenses implemented "under the hood", the actual cost might greatly depend on the implementation. See/profile the code your specific compiler generates.
Setting alternate1 value will mean calling the function, and even if the function is returning a static value, you will have to save the stack, call the function, get its return value, restore the stack and assign the value to a variable.
Literally, in the first case you will be executing at least 8 assembly code lines, and in the second one – only one line.

Nifty/Schwarz counter, standard compliant?

I had a discussion this morning with a colleague about static variable initialization order. He mentioned the Nifty/Schwarz counter and I'm (sort of) puzzled. I understand how it works, but I'm not sure if this is, technically speaking, standard compliant.
Suppose the 3 following files (the first two are copy-pasta'd from More C++ Idioms):
//Stream.hpp
class StreamInitializer;
class Stream {
friend class StreamInitializer;
public:
Stream () {
// Constructor must be called before use.
}
};
static class StreamInitializer {
public:
StreamInitializer ();
~StreamInitializer ();
} initializer; //Note object here in the header.
//Stream.cpp
static int nifty_counter = 0;
// The counter is initialized at load-time i.e.,
// before any of the static objects are initialized.
StreamInitializer::StreamInitializer ()
{
if (0 == nifty_counter++)
{
// Initialize Stream object's static members.
}
}
StreamInitializer::~StreamInitializer ()
{
if (0 == --nifty_counter)
{
// Clean-up.
}
}
// Program.cpp
#include "Stream.hpp" // initializer increments "nifty_counter" from 0 to 1.
// Rest of code...
int main ( int, char ** ) { ... }
... and here lies the problem! There are two static variables:
"nifty_counter" in Stream.cpp; and
"initializer" in Program.cpp.
Since the two variables happen to be in two different compilation units, there is no (AFAIK) official guarantee that nifty_counter is initialized to 0 before initializer's constructor is called.
I can think of two quick solutions as two why this "works":
modern compilers are smart enough to resolve the dependency between the two variables and place the code in the appropriate order in the executable file (highly unlikely);
nifty_counter is actually initialized at "load-time" like the article says and its value is already placed in the "data segment" in the executable file, so it is always initialized "before any code is run" (highly likely).
Both of these seem to me like they depend on some unofficial, yet possible implementation. Is this standard compliant or is this just "so likely to work" that we shouldn't worry about it?
I believe it's guaranteed to work. According to the standard ($3.6.2/1): "Objects with static storage duration (3.7.1) shall be zero-initialized (8.5) before any other initialization takes place."
Since nifty_counter has static storage duration, it gets initialized before initializer is created, regardless of distribution across translation units.
Edit: After rereading the section in question, and considering input from #Tadeusz Kopec's comment, I'm less certain about whether it's well defined as it stands right now, but it is quite trivial to ensure that it is well-defined: remove the initialization from the definition of nifty_counter, so it looks like:
static int nifty_counter;
Since it has static storage duration, it will be zero-initialized, even without specifying an intializer -- and removing the initializer removes any doubt about any other initialization taking place after the zero-initialization.
I think missing from this example is how the construction of Stream is avoided, this often is non-portable. Besides the nifty counter the initialisers role is to construct something like:
extern Stream in;
Where one compilation unit has the memory associated with that object, whether there is some special constructor before the in-place new operator is used, or in the cases I've seen the memory is allocated in another way to avoid any conflicts. It seems to me that is there is a no-op constructor on this stream then the ordering of whether the initialiser is called first or the no-op constructor is not defined.
To allocate an area of bytes is often non-portable for example for gnu iostream the space for cin is defined as:
typedef char fake_istream[sizeof(istream)] __attribute__ ((aligned(__alignof__(istream))))
...
fake_istream cin;
llvm uses:
_ALIGNAS_TYPE (__stdinbuf<char> ) static char __cin [sizeof(__stdinbuf <char>)];
Both make certain assumption about the space needed for the object. Where the Schwarz Counter initialises with a placement new:
new (&cin) istream(&buf)
Practically this doesn't look that portable.
I've noticed that some compilers like gnu, microsoft and AIX do have compiler extensions to influence static initialiser order:
For Gnu this is: Enable the init-priority with the -f flag and use __attribute__ ((init_priority (n))).
On windows with a microsoft compiler there is a #pragma (http://support.microsoft.com/kb/104248)

How static local POD constants are initialized? Lazily or not?

POD means primitive data type without constructor and destructor.
I am curious, how compilers handle lazy initialization of POD static local variables. What is the implication of lazy initialization if the function are meant to be run inside tight loops in multithreaded applications? These are the possible choices. Which one is better?
void foo_1() {
static const int v[4] = {1, 2, 3, 4};
}
void foo_2() {
const int v[4] = {1, 2, 3, 4};
}
How about this? No lazy initialization, but slightly clumsy syntax?
struct Bar
{
static const int v[4];
void foo_3()
{
// do something
}
};
const int My::v[4] = {1, 2, 3, 4};
When a static variable is initialized with constant data, all compilers that I'm familiar with will initialize the values at compile time so that there is no run time overhead whatsoever.
If the variable isn't static it must be allocated on each function invocation, and the values must be copied into it. I suppose it's possible that the compiler might optimize this into a static if it's a const variable, except that const-ness can be cast away.
In foo_1(), v is initialized sometime before main() starts. In foo_2(), v is created and initialized every time foo_2() is called. Use foo_1() to eliminate that extra cost.
In the second example, Bar::v is also initialized sometime before main().
Performance is more complex than just allocation. For example, you could cause an extra cache line to have to be in cache with the static variable, because it's not contiguous with other local memory that you're using, and increase cache pressure, cache misses, and suchlike. In comparison to this cost, I would say that the incredibly tiny overhead of re-allocating the array on the stack every time would be very trivial. Not just that, but any compiler is excellent at optimizing things like that, whereas it can't do anything about static variables.
In any case, I would suggest that the performance difference between the two is minimal - even for inside a tight loop.
Finally, you may as well use foo_2()- the compiler is perfectly within it's rights to make a variable like that static. As it was initially defined as const, const_casting the const away is undefined behaviour, regardless of whether or not it's static. However, it can't choose to make a static constant non-static, as you could be depending upon the ability to return it's address, for example.
An easy method to find out how variables are initialized is to print an assembly language listing of a function that has static and local variables.
Not all compiler initialize variables in the same method. Here is a common practice:
Before the main() method global variables are initialized by copying a section of values into the variables. Many compilers will place the constants into an area so that the data can be assigned using simple assembly move or copy instructions.
Local variables (variables with local scope) may be initialized upon entering the local scope and before the first statement in the scope is executed. This depends upon many factors, one of them is the constness of the variable.
Constants may be placed directly into the executable code, or they may be a pointer to a value in ROM, or copied into memory or register. This is decided by the compiler for best performance or code size, depending on the compiler's settings.
On the technical side, foo_1 and foo_3 are required to initialize their arrays before any functions, including class constructors, are called. That guarantee is essentially as good as no runtime. And in practice, most implementations don't need any runtime to initialize them.
This guarantee applies only to objects of POD type with static storage duration which are initialized with "constant expressions". A few more contrasting examples:
void foo_4() {
static const int v[4] = { firstv(), 2, 3, 4 };
}
namespace { // anonymous
const int foo_5_data[4] = { firstv(), 2, 3, 4 };
}
void foo_5() {
const int (&v)[4] = foo_5_data;
}
The data for foo_4 is initialized the first time foo_4 is called. (Check your compiler documentation to find out whether this is thread-safe!)
The data for foo_5 is initialized at some time before main() but might be after some other dynamic initializations.
But none of this really answers questions about performance, and I'm not qualified to comment on that. #DeadMG's answer looks helpful.
You have a static initialization in all those cases, all your static variables will be initialized by the virtue of loading data segment into memory. The const in foo_2 can be initialized away if compiler finds it possible.
If you had a dynamic initialization, then initialization of variables in the namespace scope can be deferred until their first use. Similarly, dynamic initialization of local static variables in the scope of function can be performed during the first pass through the function or earlier. Additionally, compiler can statically initialize those variables if it's able to do that. I don't remember the exact verbiage from the Standard.