The following is adapted from a code:
void func()
{
static MyClass a = init_func();
a_global_var = null;
}
Does C++ compiler guarantees that the first assignment is before the 2nd?
Yes. But I shudder to think why you need to rely on this.
The first time the function is called, a is initialized with whatever is returned from init_func before a_global_var is later set to "null"
Note that as a is static, this only happens the first time the function is called. All subsequent times, a_global_var is set to null without any change to a by this function.
The first line is not an "assignment". It is an initialization. Since it is an initialization of a static object declared in block scope, it will be performed only once, when the control passes over it for the very first time, i.e. when you call your function for the first time.
The second line is indeed an assignment. It will be executed every time the control passes over it, i.e. every time you call your function.
This means that your question only makes sense for the first time this function is called. In that case the initialization is guaranteed to precede the assignment. In all subsequent calls the question will not apply at all, since the initialization will not be performed anymore.
"Does C++ compiler guarantees that the first assignment is before the 2nd?"
Yes, it's guaranteed.
Anyway you should consider to handle this in a singleton (if you really need to have it globally accessible):
class MyClass {
public:
static MyClass& instance() { // <<< replaces func()
static MyClass a;
return a;
}
void* global_var() { return a_global_var; }
private:
MyClass() : a_global_var(nullptr) { // <<< replaces init_func()
}
void* a_global_var;
};
Related
Static locals are guaranteed to be instantiated at first use by the C++ standard. However, I'm wondering what happens if I access a static local object while it is beeing constructed. I assume that this is UB.
But what are the best practices to avoid this in the following situation?
A problem situation
The Meyers Singleton pattern uses a static local in a static getInstance() method to construct the object on the first use. Now if the constructor (directly or indireclty) calls getInstance() again, we face
a situation where the static initialization is not yet completed. Here is a minimal example, that illustrates the problem situation:
class StaticLocal {
private:
StaticLocal() {
// Indirectly calls getInstance()
parseConfig();
}
StaticLocal(const StaticLocal&) = delete;
StaticLocal &operator=(const StaticLocal &) = delete;
void parseConfig() {
int d = StaticLocal::getInstance()->getData();
}
int getData() {
return 1;
}
public:
static StaticLocal *getInstance() {
static StaticLocal inst_;
return &inst_;
}
void doIt() {};
};
int main()
{
StaticLocal::getInstance()->doIt();
return 0;
}
In VS2010, this works without problems, but VS2015 deadlocks.
For this simple, reduced situation, the obvious solution is to direclty call getData(), without calling getInstance() again. However, in more complex scenarios (as my actual situation), this solution is not feasible.
Attempting a solution
If we change the getInstance() method to work on a static local pointer like this (and thus abandon the Meyers Singleton pattern):
static StaticLocal *getInstance() {
static StaticLocal *inst_ = nullptr;
if (!inst_) inst_ = new StaticLocal;
return inst_;
}
It is clear that we get an endless recursion. inst_ is nullptr on the first invokation, so we call the constructor with new StaticLocal. At this point, inst_ is still nullptr as it will only get assigned when
the constructor finishes. However, the constructor will call getInstance() again, finding a nullptr in inst_, and thus call the constructor again. And again, and again, ...
A possible solution is to move the constructor's body into the getInstance():
StaticLocal() { /* do nothing */ }
static StaticLocal *getInstance() {
static StaticLocal *inst_ = nullptr;
if (!inst_) {
inst_ = new StaticLocal;
inst_->parseConfig();
}
return inst_;
}
This will work. However, I'm not happy with this situation, as a constructor should, well, construct a complete object. It is debateable if this situation can be made an exception, as it is a singleton. However, I dislike it.
But what's more, what if the class has a non-trivial destructor?
~StaticLocal() { /* Important Cleanup */ }
In the above situation, the destructor is never called. We loose RAII and thus one important distinguishing feature of C++! We are in a world like Java or C#...
So we could wrap our singleton in some sort of smart pointer:
static StaticLocal *getInstance() {
static std::unique_ptr<StaticLocal> inst_;
if (!inst_) {
inst_.reset(new StaticLocal);
inst_->parseConfig();
}
return inst_.get();
}
This will correctly call the destructor on program exit. But it forces us to make the destructor public.
At this point, I feel I'm doing the compiler's job...
Back to the original question
Is this situation really undefined behaviour? Or is it a compiler bug in VS2015?
What is the best solution to such a situation, prefably without dropping a full constructor, and RAII?
This leads to undefined behaviour by c++ 11 standard. The relevant section is 6.7:
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.
The example from the standard is bellow:
int foo(int i) {
static int s = foo(2*i); // recursive call - undefined
return i+1;
}
You are facing the deadlock since MSVC inserts mutex lock/unlock to make static variable initialization thread safe. Once you call it recursively, you are locking the same mutex two times in the same thread, what leads to dead lock.
This is how static initialization is implemented internally in llvm compiler.
The best solution IMO is to do not use singletons at all. Significant group of developers tend to think that singleton is anti-pattern. The issues like you mentioned is really hard to debug, because it occurs before main. Because order of globals initialization is undefined. Also, multiple translation units might be involved, so compiler won't catch this types of errors. So, when I faced the same problem in production code, I was obliged to remove all of the singletons.
If you still think that singleton is the right way to go, then you need to re-structurize your code somehow when your singleton object owns (holds them as members, for example) all the classes that calls GetInstance during the singleton initialization. Think of your classes like ownership tree, where the singleton is the root. Pass reference to parent, when you create a child, if child needs it.
The problem is that inside the class, you should be using "this" instead of calling getInstance, in particular:
void parseConfig() {
int d = StaticLocal::getInstance()->getData();
}
Should simply be:
void parseConfig() {
int d = getData();
}
The object is a singleton because the constructor is private and thus the user cannot construct an arbitrary number of objects. It's bad design to write the whole class assuming there will be only one instance of the object ever. At some point somebody may stretch the concept of a singleton like this:
static StaticLocal *getInstance(int idx) {
static StaticLocal inst_[3];
if (idx < 0 || idx >= 3)
throw // some error;
return &inst_[idx];
}
When that happens, it's much easier to update the code if there aren't calls to getInstance() throughout the class.
Why do changes like this happen? Imagine you were writing a class 20 years ago to represent the CPU. Of course there will only ever be one CPU in the system, so you make it a singleton. Then, suddenly, multi-core systems become commonplace. You still want only as many instances of the CPU class as there are cores in the system, but you won't know until the program is run how many cores are actually on a given system.
Moral of the story: Using the this pointer not only avoids recursively calling getInstance(), but future proofs your code as well.
Actually this code in its current form is stuck into 3-way infinite recursion. Hence it will never work.
getInstance() --> StaticLocal()
^ |
| |
----parseConfig() <---
To let it work, anyone of the above 3 methods has to compromise and come out of the vicious circle. You judged it right, parseConfig() is the best candidate.
Let's assume that all the recursive content of constructor is put into parseConfig() and non-recursive contents are retained in constructor. Then you may do following (only relevant code):
static StaticLocal *s_inst_ /* = nullptr */; // <--- introduce a pointer
public:
static StaticLocal *getInstance() {
if(s_inst_ == nullptr)
{
static StaticLocal inst_; // <--- RAII
s_inst_ = &inst_; // <--- never `delete s_inst_`!
s_inst_->parseConfig(); // <--- moved from constructor to here
}
return s_inst_;
}
This works fine.
One straight forward way of solving this is to separate the responsibilities, in this case "whatever StaticLocal is supposed to do" and "reading the configuration data"
class StaticLocal;
class StaticLocalData
{
private:
friend StaticLocal;
StaticLocalData()
{
}
StaticLocalData(const StaticLocalData&) = delete;
StaticLocalData& operator=(const StaticLocalData&) = delete;
int getData()
{
return 1;
}
public:
static StaticLocalData* getInstance()
{
static StaticLocalData inst_;
return &inst_;
}
};
class StaticLocal
{
private:
StaticLocal()
{
// Indirectly calls getInstance()
parseConfig();
}
StaticLocal(const StaticLocal&) = delete;
StaticLocal& operator=(const StaticLocal&) = delete;
void parseConfig()
{
int d = StaticLocalData::getInstance()->getData();
}
public:
static StaticLocal* getInstance()
{
static StaticLocal inst_;
return &inst_;
}
void doIt(){};
};
int main()
{
StaticLocal::getInstance()->doIt();
return 0;
}
This way, StaticLocal does not call itself, the circle is broken.
Also, you have cleaner classes. If you move the implementation of StaticLocal into a separate compile unit, users of static local won't even know that the StaticLocalData thingy exists.
There is a good chance that you will find that you do not need the functionality of StaticLocalData to be wrapped into a Singleton.
All versions of the C++ standard have a paragraph that makes this undefined behaviour. In C++98, Section 6.7 para 4.
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. If control reenters the declaration (recursively)
while the object is being initialized, the behavior is undefined.
All subsequent standards have essentially the same paragraph (only differences are inconsequential - such as section numbering for cross-referencing, etc).
What you have done is implement the constructor of your singleton so it calls the function which constructs it. getInstance() creates the object, the constructor (indirectly) calls getInstance(). Hence it runs afoul of the last sentence in the quote above, and introduces undefined behaviour.
The solution, as with anything recursive, is to either reimplement so recursion does not occur, or to prevent interference between the first call and any recursive calls.
There are three ways to achieve this.
The first, which you have said you don't want, is to construct an object and then parse data to initialise it (two-stage construction).
The second is to parse the data first, and only construct the object if the parsed data is valid (i.e. suitable for use in constructing the object).
The third is for the constructor to handle the parsing (which you are trying to do) but, if parsed data is invalid, to force the constructor to fail (which your code does not do).
An example of the third is to leave the getInstance() alone, and restructure the constructor so it never calls getInstance().
static StaticLocalData* getInstance()
{
static StaticLocalData inst_;
return &inst_;
}
StaticLocalData::StaticLocalData()
{
parseConfig();
}
void StaticLocalData::parseConfig()
{
int data = getData(); // data can be any type you like
if (IsValid(data))
{
// this function is called from constructor so simply initialise
// members of the current object using data
}
else
{
// okay, we're in the process of constructing our object, but
// the data is invalid. The constructor needs to fail
throw std::invalid_argument("Construction of static local data failed");
}
}
In the above, IsValid() represents a function or expression that checks if the parsed data is valid.
This approach actually exploits the second last sentences in the paragraph I quoted above from the standard. It has the effect of ensuring that calling staticLocal::getInstance() repeatedly will keep resulting in an exception until the parsing succeeds. Once the parsing has succeeded, the object will exist, and no further attempt will be made to it (it's address will simply be returned instead).
If the caller does not catch the exception, the effect is simple - the program will terminate(). If the caller does catch the exception, it should not try to use the pointer.
try
{
StaticLocal *thing = StaticLocal::getInstance();
// code using thing here will never be reached if an exception is thrown
}
catch (std::invalid_argument &e)
{
// thing does not exist here, so can't be used
// Worry about recovery, not trying to use thing
}
So, yes, your approach introduces undefined behaviour. But same part of the standard that makes the behaviour undefined also provides the basis for a solution.
In terms of dtor, I think you don't have to worry about it. Once you define it, then it will be automatically called after main() exits.
see How to implement multithread safe singleton in C++11 without using <mutex>
singleton declaration in c++11 is thread safe by standard. In VS2015 it may be implemented by mutex.
So, you last solution is fully applicable
StaticLocal() { /* do nothing */ }
static StaticLocal *getInstance() {
static StaticLocal inst_;
std::call_once(once_flag, [&inst_]() {inst_.parseConfig(); return &inst_;});
return &inst_;
}
about destructor: you can register you singleton destructor by using
int atexit(void (*function)(void));. This applied in Linux and may be exist in Win too, as function from standard library.
Say I have a C++ function:
void foo(int x) {
static int bar = x;
}
If I call foo(3) then afterwards call foo(4), it is my understanding that the value of bar will still be 3. Why is this? I understand why the memory allocation part of the initialization is redundant. but why is the assignment also ignored?
It is not an "assignment". It is an initialization. And, per rules of C++ language, initialization of static objects is performed only once - when the control passes over the declaration for the very first time.
In your example, the control passes over the declaration of bar when x is 3. So, bar is initialized with 3. It will never be "reinitialized", i.e. calling foo(4) will not affect bar at all. If you want to change the value of bar after that, you have to modify bar directly.
Short answer: because the standard says so.
Long answer: that's not an assignment, but an initialisation, and it's ignored because the standard says so.
Consider some different static variables:
void foo(int x) {
static int bar = x;
static std::string s1 = "baz";
static std::string s2("baz");
static int i{2}; // C++11-style uniform initialization
}
Do you also think s1 should get "assigned" the value "baz" every time the function is called? What about s2? What about i?
None of those statements perform any assignment, they are all initializations, and they are only done once. Just because a statement includes the = character doesn't make it an assignment.
A reason why the language is defined to work that way is that it's common to use a local static variable to run a function once:
bool doInit()
{
// run some one-time-only initialization code
// ...
return true;
}
void func() {
static bool init = doInit();
// ...
}
If init got assigned a value again every time the function is called then doInit() would get called multiple times, and would fail its purpose of running one-time-only setup.
If you want to change the value every time it's called, that's easy ... just change it. But if you don't want it to keep changing then there would be no way to do that if the language worked the way you are asking about.
It would also be impossible to have static const local variable:
void func() {
static const bool init = doInit();
// ...
}
Oops, this would try to change the value of init every time it's called.
The memory location for bar is not valid until the first call to foo, which is when bar gets instantiated. bar gets initialized to x when it gets instantiated. Every call to foo afterward, bar is already instantiated and therefore already initialized.
this is initialization of static variable instead of assigning values to it. with that being said, the value of bar would always be 3 if u call foo(3) at the very first place.
In C++, when a function is called, a new stack frame is added to the call stack, containing its parameters and local variables (and other things). Does this also happen when an object constructor is called?
If so, does this change when the constructor uses an initialization list? What is the structure of this stack frame? Does it contain the object's member variables (which must be in the heap after the execution of the constructor)?
You don't need to think constructor especially. It's just a kind of function - for example, This C++ code is
class Test
{
private:
int m_a;
public:
Test() : m_a(0) { puts("Test::Test()"); }
explicit Test(int i) : m_a(i) { puts("Test::Test(int)"); }
void f(char c) { puts("Test::f(char)"); }
~Test() { puts("Test::~Test()");
};
int main()
{
Test t1;
Test t2(3);
t1.f('a');
}
almost similar to
struct Test
{
int m_a;
};
void Test__ctor_0(Test *thiz) { thiz->m_a = 0; puts("Test::Test()"); }
void Test__ctor_1(Test *thiz, int i) { thiz->m_a = i; puts("Test::Test(int)"); }
void Test__f(Test *thiz, char c) { puts("Test::f(char)"); }
void Test__dtor_(Test *thiz) { puts("Test::~Test()"); }
int main()
{
struct Test t1;
Test__ctor_0(&t1);
struct Test t2;
Test__ctor_1(&t2, 3);
Test__f(&t1, 'a');
Test__dtor_(&t1);
Test__dtor_(&t2);
}
this C code.
Of course, the stack frame can be created when you call ctor, if it's not inlined or compiler optimizes call not to create stack frame to reduce the decrease of performance.
(In cdecl of x86, this pointer is sent through ecx register, unlike other parameter. So if the constructor don't use any local variables and don't have any additional parameters, stack frame could be not created.)
Construction is handled like any other method call.
If it doesn't get inlined by the optimizer, a stack frame will be created holding an implicit "this" pointer and all passed-in parameters.
Most architectures' ABIs call member functions by putting the this-pointer into a specific register, or by pushing it onto the stack at a particular position. Constructors are a little unusual language-wise, but from the point of view of the ABI they follow this pattern.
In general, the this-pointer is treated as an implicit first argument to the function. For instance, under the normal x86 calling convention, a pointer to the object is at the "bottom" (memory-order-wise) of the stack. The member variables themselves aren't on the stack; that wouldn't make any sense, because the constructor (as with other member functions) might need to write to those variables, and those writes would need to affect the "real" copy of the object. Hence pushing a pointer to them instead.
Object construction involves more than just the execution of constructor body. First off, all the base subobjects and member subobjects are initialized, and only then does the contructor body run. So when a particular constructor is selected for object construction, the subobject constructors run first, and their arguments are given by the original constructor's initializer list. Afterwards, the constructor body runs, more or less like a normal function, with parameters populated from the constructor arguments.
Having a simple class:
class A {
public:
A() {}
void set(int value) { value_ = value; }
private:
int value_;
};
and its global instance:
A a;
Is it OK to call method set on a not yet constructed object a? That can happen when for example a.set(123) is called from a constructor of another global object in another translation unit.
Will the value in the object a set by calling a.set(123) remain when the non-parametric and empty constructor of A is later called for object a?
Is it ok to call method set on a not yet constructed object a?
No. You may not call member functions for an object that has not yet begun construction.
(Since the answer is no, your second question requires no answer.)
If you may need to access this global instance from multiple translation units during dynamic initialization, you can use the Meyers singleton technique:
A& global_a()
{
static A a;
return a;
}
a will be initialized when global_a() is first called. Note that in a multithreaded program you may need to concern yourself with synchronization of the initialization.
When you write
A a;
a is a constructed object now. In case A is a then A default constructor was already been called
If in 1) you mean it's ok to call set in the constructor, then yes, that's fine because it isn't a virtual method. You cannot call a virtual method in the constructor.
As for 2), what you're asking isn't really clear. The constructor is only called once (although there are ways around that sort of thing, but don't do them) and that is when the object is first created. You can't call the constructor on a a second time so the question doesn't really make sense.
I wanted to run 1,000 iterations of a program, so set a counter for 1000 in main. I needed to reinitialize various variables after each iteration, and since the class constructor had all the initializations already written out - I decided to call that after each iteration, with the result of each iteration being stored in a variable in main.
However, when I called the constructor, it had no effect...it took me a while to figure out - but it didn't reinitialize anything!
I created a function exactly like the constructor - so the object would have its own version. When I called that, it reinitialized everything as I expected.
int main()
{
Class MyClass()
int counter = 0;
while ( counter < 1000 )
{ stuff happens }
Class(); // This is how I tried to call the constructor initially.
// After doing some reading here, I tried:
// Class::Class();
// - but that didn't work either
/* Later I used...
MyClass.function_like_my_constructor; // this worked perfectly
*/
}
...Could someone try to explain why what I did was wrong, or didn't work, or was silly or what have you? I mean - mentally, I just figured - crap, I can call this constructor and have all this stuff reinitialized. Are constructors (ideally) ONLY called when an object is created?
Your line Class(); does call the constructor of the class Class, but it calls it in order to create a "temporary object". Since you don't use that temporary object, the line has no useful effect.
Temporary objects (usually) disappear at the end of the expression in which they appear. They're useful for passing as function parameters, or initializing other objects. It's almost never useful to just create one in a statement alone. The language allows it as a valid expression, it's just that for most classes it doesn't do very much.
There is no way in C++ to call a constructor on an object which has already been constructed. The lifecycle of a C++ object is one construction, and one destruction. That's just how it works. If you want to reset an object during its life, you've done the right thing, which is to call a function to reset it. Depending on your class you might not need to write one - the default assignment operator might do exactly what you need. That's when a temporary can come in handy:
Class myObject;
// ... do some stuff to myObject ...
myObject = Class();
This updates myObject with the values from the freshly-constructed temporary. It's not necessarily the most efficient possible code, since it creates a temporary, then copies, then destroys the temporary, rather than just setting the fields to their initial values. But unless your class is huge, it's unlikely that doing all that 1000 times will take a noticeable amount of time.
Another option is just to use a brand new object for each iteration:
int main() {
int counter = 0;
while (counter < 1000) {
Class myObject;
// stuff happens, each iteration has a brand new object
}
}
Note that Class MyClass(); does not define an object of type Class, called MyClass, and construct it with no parameters. It declares a function called MyClass, which takes no parameters and which returns an object of type Class. Presumably in your real code, the constructor has one or more parameters.
What happens in that line reading...
Class ();
Is that you do in fact call the constructor - for a temporary object that is being constructed from scratch, and which is then immediately destructed since you're not doing anything with it. It's very much like casting to Class, which creates a value using a constructor call, except that in this case there's no value to cast so the default constructor is used.
It's possible that the compiler then optimises this temporary away, so there's no constructor at all - I'm not sure whether that's allowed or not.
If you want to re-initialise members, calling the constructor isn't the way to do it. Move all your initialisation code into another method and call that from your constructor, and when you want to re-initialise, instead.
Yes, this not typical usage. Create a function that resets your variables, and call the method whenever you need it.
You fell prey to a common misreading of c++. The new c++0x makes things a bit clearer.
The problem is constructions syntax looks like a function call.
void foo( int i ) { }
class Foo { };
Foo(10); // construct a temporary object of type foo
foo(10); // call function foo
Foo{10}; // construct a temporary object of type foo in c++0x syntax
I think the c++0x syntax is more clear.
You could do what you want with this syntax. But beware it is very advanced and you should not do it.
MyClass.~Class(); // destruct MyClass
new( &MyClass ) Class;
With such requirements, I generally write a clear() (public) method. I call it from constructor, destructor. User code can call it whenever it wants to.
class Foo
{
public:
Foo() { clear(); }
~Foo() { clear(); }
void clear(); // (re)initialize the private members
private:
// private members
};
To answer the question here, the clear() method may be called whenever it is required to re-initialize the class as it was just after the initial construction.