I'm having some problems initializing static string members in c++. I have several classes and each one is holding several static string members that represent an id. When I am initializing the variables by calling a static function everything is fine. However, when I'd like to assign one variable with the value of another it still holds empty string. What's problem with this code?
std::string A::id()
{
std::stringstream sst;
sst << "id" << i;
i++;
return sst.str();
}
std::string B::str = A::id(); //prints "id0";
std::string C::str = "str"; //prints str
std::string D::str = B::str; //prints "" <-- what's wrong here?
std::string D::str2 = C::str; //prints ""
It appears as if the variables I am referring to (B::str and C::str) havent been initialized yet. But I assume when D::str = B::str is executed C::str is initialized at the latest and therefore D::str should also hold the string "id0".
This is Static Initialization Fiasco.
As per the C++ Standard the initialization order of objects with static storage duration is unspecified if they are declared in different Translation units.
Hence any code that relies on the order of initialization of such objects is bound to fail, and this problem is famously known as The Static Initialization Fiasco in C++.
Your code relies on the condition that Initialization of B::str and C::str happens before D::str, which is not guaranteed by the Standard. Since these 3 static storage duration objects reside in different translation units they might be initialized in Any order.
How to avoid it?
The solution is to use Construct On First Use Idiom,in short it means replacing the global object, with a global function, that returns the object by reference. The object returned by reference should be local static, Since static local objects are constructed the first time control flows over their declaration, the object will be created only on the first call and on every subsequent call the same object will be returned, thus simulating the behavior you need.
This should be an Interesting read:
How do I prevent the "static initialization order fiasco"?
There is no guaranteed order of initialization for static variables. So don't rely on it.
Instead init them with actual literal's, or better yet, init them at run-time when they are really needed.
Related
In general, I would like to know where a member's static function's local variables are stored? I.e. if a static variable is only used inside a static function, is the variable only initialized once?
Please refer to the code below
std::string const CONST1 = "const1";
std::string const CONST2 = "const2";
std::string const CONST3 = "const3";
class Test
{
public:
static const std::vector<std::string> GetSomeMap();
}
const std::vector<std::string> Test::GetSomeMap()
{
static std::vector<std::string> SomeMap = boost::assign::list_of(CONST1)(CONST2)(CONST3);
return SomeMap;
}
With the above code, is there an advantage to declaring SomeMap as static? (I am expecting it to be only initialized once.)
if a Static variable is used inside a static function is the variable only initialised once ?
The answer is "yes".
It is also "yes" for static variables of regular, i.e. non-static, member functions.
It is also "yes" for static variables of non-member functions.
Static variables inside functions (regardless of the type of function) are stored in the "DATA" segment, just like global variables. So you could say that in this way, function static variables are similar to global ones, just that they are only accessible by name within a limited scope (the function body).
If a variable is static ,it is stored in heap.
If a variable is a member of static function, it is stored in static local variable.
And, they are only initialised once.
In General I would like to ask where a Member Static function's local variables are stored ?
Depends. A static constant plain old datatype may be stored in a read-only data segment. A static variable with constant initializer may be stored in the data segment, and a static variable that requires dynamic initialization may be stored in the BSS segment.
if a Static variable is used inside a static function is the variable only initialised once ?
Yes. In this case, SomeMap will be initialized the first time control passes through its declaration.
The zero-initialization (8.5) of all local objects with static storage duration (3.7.1) is performed before any
other initialization takes place. A local object of POD type (3.9) with static storage duration initialized with
constant-expressions is initialized before its block is first entered. An implementation is permitted to perform
early initialization of other local objects with static storage duration under the same conditions that an
implementation is permitted to statically initialize an object with static storage duration in namespace scope
(3.6.2). Otherwise such an object is initialized the first time control passes through its declaration; such an
object is considered initialized upon the completion of its initialization. If the initialization exits by throwing
an exception, the initialization is not complete, so it will be tried again the next time control enters the
declaration.
Section 6.7, paragraph 4 of ISO/IEC 14882:2003(E) (sorry, I don't have a more recent copy of the standard handy)
From the above code, is there an advantage of declaring SomeMap as static ?( I expect it to be only initialized once )
Yes there is an advantage to declaring it static -- it will only be initialized once and only initialized if it is used. If Test::GetSomeMap is never call, SomeMap is never initialized.
As #Blacktempel states above, however, Test::GetSomeMap should return by reference to remove any doubts about the creation of extra copies SomeMap.
You should also note that you are incurring the cost of the creation of three strings (CONST1, CONST2, and CONST3), each of which may allocate heap memory to store the a copy of their constant-expression character string initializers ("const1", "const2", "const3"). Furthermore, if you call Test::GetSomeMap, you are also incurring the cost of initializing the SomeMap vector which may also allocate heap memory to store the copies of the strings.
If you are concerned about memory usage and initialization overhead and you truly want a static constant array of strings, just declare one, like so:
static const char* const * GetSomeMap(void) {
static const char* const SomeMap[] = {"const1", "const2", "const3"};
return SomeMap;
}
SomeMap will consume a minimum of memory with no initialization overhead (and be completely unchangeable).
Let's say I create:
class Hello {
public:
int World(int in)
{
static int var = 0; // <<<< This thing here.
if (in >= 0) {
var = in;
} else {
cout << var << endl;
}
}
};
Now, if I do:
Hello A;
Hello B;
A.World(10);
A.World(-1);
B.World(-1);
I'm getting output of "10" followed by another "10". The value of the local variable of a method just crossed over from one instance of a class to another.
It's not surprising - technically methods are just functions with a hidden this parameter, so a static local variable should behave just like in common functions. But is it guaranteed? Is it a behavior enforced by standard, or is it merely a happy byproduct of how the compiler handles methods? In other words - is this behavior safe to use? (...beyond the standard risk of baffling someone unaccustomed...)
Yes. It doesn't matter if the function is a [non-static] member of a class or not, it's guranteed to have only one instance of it's static variables.
Proper technical explanation for such variables is that those are objects with static duration and internal linkage - and thus those names live until program exits, and all instances of this name refer to the same entity.
Just one thing to add to the correct answer. If your class was templated, then the instance of var would only be shared amongst objects of the same instantiation type. So if you had:
template<typename C>
class Hello {
public:
int World(int in)
{
static int var = 0; // <<<< This thing here.
if (in >= 0) {
var = in;
} else {
cout << var << endl;
}
}
};
And then:
Hello<int> A;
Hello<int> B;
Hello<unsigned> C;
A.World(10);
A.World(-1);
B.World(-1);
C.World(-1);
Then the final output would be "0" rather than "10", because the Hello<unsigned> instantiation would have its own copy of var.
If we are talking about the Windows Compiler it's guaranteed
https://msdn.microsoft.com/en-us/library/y5f6w579.aspx
The following example shows a local variable declared static in a member function. The static variable is available to the whole program; all instances of the type share the same copy of the static variable.
They use an example very similar to yours.
I don't know about GCC
Yes, it is guaranteed. Now, to answer the question "Any risk of sharing local static variable of a method between instances?" it might be a bit less straightforward. There might be potential risks in the initialization and utilization of the variable and these risks are specific to variables local to the method (as opposed to class variables).
For the initialization, a relevant part in the standard is 6.7/4 [stmt.dcl]:
Dynamic initialization of a block-scope variable with static storage
duration (3.7.1) or thread storage duration (3.7.2) is performed the
first time control passes through its declaration; such a variable is
considered initialized upon the completion of its initialization. If
the initialization exits by throwing an exception, the initialization
is not complete, so it will be tried again the next time control
enters the declaration. If control enters the declaration concurrently
while the variable is being initialized, the concurrent execution
shall wait for completion of the initialization. If control
re-enters the declaration recursively while the variable is being
initialized, the behavior is undefined.
In the simple cases, everything should work as expected. When the construction and initialization of the variable is more complex, there will be risks specific to this case. For instance, if the constructor throws, it will have the opportunity to throw again on the next call. Another example would be recursive initialization which is undefined behavior.
Another possible risk is the performance of the method. The compiler will need to implement a mechanism to ensure compliant initialization of the variable. This is implementation-dependent and it could very well be a lock to check if the variable is initialized, and that lock could be executed every time the method is called. When that happens, it can have a significant adverse effect on performance.
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)
bool SomeClass::Function( bool thankYou = true )
{
static bool justAbool = false;
// Do something with justAbool;
...
}
I have searched around but I can't find anything about this except globals vars or member functions itself.
What does the above do, i.e. what happens, does justAbool keep its value after leaving the scope? Or does it 'remember' the value when it re-enters the scope?
The variable justAbool is initialized to false only once and it is initialized before the function is entered. The value will be remembered after leaving the scope of the function. It is important to note that the value will also be shared by all instances of SomeClass just like a static member variable. The variable justAbool will not be re-initialized if you create a new instance of your class and then call the function again.
static when applied to a local variable gives that variable static storage duration. This means that the justAbool's lifetime lasts to the end of the program rather than to the end of the invocation of the function. It's scope stays the same, it can only be accessed by name in the function, after the declaration appears.
justAbool will be initialized (using the supplied initializer = false) the first time that the function is called. Thereafter it will retain its previous value, it will not be reinitialized when the function is called again.
Here are some fuller details about storage duration and lifetimes, with references to the standard.
If an object has static storage duration, it means that the storage for the object lasts for the duration of the program (beginning to end). (3.7.1 [basic.stc.static])
As a bool is a type without a non-trivial constructor, its lifetime mirrors that of its storage, i.e. it lives from the beginning to the end of the program. (3.8 [basic.life])
All objects with static storage duration (including local objects) are zero-initialized before any other initialization. (6.7/4 [stmt.decl]) [For local objects with an initializer this is fairly academic because there is no way to read their value before their declaration is reached.]
Local objects of POD type with static storage duration initialized with constant-expressions are initialized before their block is entered, otherwise local objects with static storage duration are initialized when control passes through their declaration. (6.7/4 again)
An implementation is permitter, but not required, to perform early initialization in some situations.
The above function does what it does in the comment // Do something with justAbool;.
On a serious note, yes, the static variable (in this case justAbool) inside a function retains it's value even after returning from the function. It gets initialized ONLY ONCE. And each successive calls uses it as if it's a global variable. Its life-time is equal to the end of the program.
int f()
{
static int v = 0;
return ++v;
}
int main()
{
cout << f() << endl;
cout << f() << endl;
cout << f() << endl;
cout << f() << endl;
}
Output:
1
2
3
4
Online Demo : http://www.ideone.com/rvgB5
The justAbool is actually a regular static variable - it exists from the start of the program and is initialized only once. The special thing is that is is known only in this function - if you try and use it outside the function the compiler won't know what it is.
justAbool keeps its value after leaving the scope. What else did you want this code to do exactly?
function level static local variable, the initialization depends on variable types:
POD: initialized before main()
non-POD: initialized the first time, the line in the function is executed.
Is global memory initialized in C++? And if so, how?
(Second) clarification:
When a program starts up, what is in the memory space which will become global memory, prior to primitives being initialized? I'm trying to understand if it is zeroed out, or garbage for example.
The situation is: can a singleton reference be set - via an instance() call, prior to its initialization:
MySingleton* MySingleton::_instance = NULL;
and get two singleton instances as a result?
See my C++ quiz on on multiple instances of a singleton...
From the standard:
Objects with static storage duration (3.7.1) shall be zero-initialized (8.5) before any other initialization takes place. Zero-initialization and initialization with a constant expression are collectively called static initialization; all other initialization is dynamic initialization. Objects of POD [plain old data] types (3.9) with static storage duration initialized with constant expressions (5.19) shall be initialized before any dynamic initialization takes place. Objects with static storage duration defined in namespace scope in the same translation unit and dynamically initialized shall be initialized in the order in which their definition appears in the translation unit. [Note:8.5.1 describes the order in which aggregate members are initialized. The initial-
ization of local static objects is described in 6.7.]
So yes, globals which have static storage duration will be initialized. Globals allocated, e.g., on the heap will of course not be initialized automatically.
Yes global primitives are initialized to NULL.
Example:
int x;
int main(int argc, char**argv)
{
assert(x == 0);
int y;
//assert(y == 0); <-- wrong can't assume this.
}
You cannot make any assumptions about classes, structs, arrays, blocks of memory on the heap...
It's safest just to always initialize everything.
Coming from the embedded world...
Your code gets compiled into three types of memory:
1. .data: initialized memory
2. .text: constants and code
3. .bss: uninitialized memory (initialized to 0 in C++ if not explicitly initialized)
Globals go in .data if initialized. If not they are placed in .bss and zero'ed in premain code.
Variables declared with static/global scope are always initialized under VC++ at least.
Under some circumstances there can actually be a difference in behaviour between:
int x = 0;
int main() { ... }
and
int x;
int main() { ... }
If you are using shared data segments then VC++ at least uses the presence of an explicit initialization along with a #pragma data_seg to determine whether a particular variable should go in the shared data segment or the private data segment for a process.
For added fun consider what happens if you have a static C++ object with constructor/destructor declared in a shared data segment. The constructor/destructor is called every time the exe/dll attaches to the data segment which is almost certainly not what you want.
More details in this KB article