Local static object and exception - c++

How should I work with exceptions throwed from constructors of local static objects? For example I have following code:
class A
{
public:
A() {throw runtime_error("Ooops");}
};
void foo()
{
static A a = A();
cout << "Continue" << endl;
}
int main(void)
{
try
{
foo();
}
catch(...)
{
}
foo(); // Prints continue
return 0;
}
As I understand, in the case of second calling foo method, object a is treated as fully constructed object, and constructor is not called. (More over, it seems like destructor of a due first exception throwing is not called)

If that's true, then that is a compiler bug.
(However, VTT claims that this code produces the expected result with Visual Studio 2015, so I recommend double-checking your results.)
Here's the standard-mandated behaviour:
[C++14: 6.7/4]: The zero-initialization (8.5) of all block-scope variables with static storage duration (3.7.1) or thread storage duration (3.7.2) is performed before any other initialization takes place. Constant initialization (3.6.2) of a block-scope entity with static storage duration, if applicable, is performed before its block is first entered. An implementation is permitted to perform early initialization of other block-scope variables with static or
thread storage duration under the same conditions that an implementation is permitted to statically initialize a variable with static or thread storage duration in namespace scope (3.6.2). Otherwise such a variable is initialized 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. [..]
GCC 6.3.0 correctly attempts to reconstruct the A (and thus throws again).
More over, it seems like destructor of a due first exception throwing is not called
No, it won't be. You can't destroy an object that was never successfully created in the first place.
[C++14: 15.2/2]: An object of any storage duration whose initialization or destruction is terminated by an exception will have destructors executed for all of its fully constructed subobjects (excluding the variant members of a union-like class), that is, for subobjects for which the principal constructor (12.6.2) has completed execution and the destructor has not yet begun execution. Similarly, if the non-delegating constructor for an object has completed execution and a delegating constructor for that object exits with an exception, the object’s destructor will be invoked. If the object was allocated in a new-expression, the matching deallocation function (3.7.4.2, 5.3.4, 12.5), if any, is called to free the storage occupied by the object.
By the way, this doesn't fix the problem, but you should just write:
static A a;
The copy-initialisation from a temporary is pointless.

Each instance of static local variable also implicitly creates a global Boolean variable that will be set to true after static variable is constructed. If constructor throws than the next time method is called there will be another attempt to construct a static variable.

Related

std::atexit ordering when called from a global object's constructor

cppreference says about std::atexit :
The functions may be called concurrently with the destruction of the objects with static storage duration and with each other, maintaining the guarantee that if registration of A was sequenced-before the registration of B, then the call to B is sequenced-before the call to A, same applies to the sequencing between static object constructors and calls to atexit
I understand that passage to mean that, if std::atexit is called during static initialization, the registered function will be called during the destruction of static objects just before the destruction of the static object which was last initialized when the std::atexit that registered the function was called. I also interpret "may be called concurrently" to mean the calls can occur between static object destructions as opposed to the multi-threaded interpretation of the word.
What I'm wondering is whether a object is considered as initialized (in the context of this ordering) when it's initialization begins or when it completes. I wrote a short test to test this :
#include <cstdlib>
#include <iostream>
struct foo
{
foo()
{
std::cout << "ctor\n";
std::atexit([]() { std::cout << "atexit\n"; });
}
~foo()
{
std::cout << "dtor\n";
}
};
foo my_foo;
int main()
{
return 0;
}
The output I get is (http://cpp.sh/3bllu) :
ctor
dtor
atexit
This leads me to believe that my_foo is not considered to be initialized in this context until it's construction finishes. In other words, the function is considered to have been registered before my_foo was initialized so the registered function executes after my_foo's destruction.
I can't seem to find anything that would guarantee this behavior and I'm not even entirely sure my initial interpretation of the cited passage is correct. Is the behavior I've described something that I can rely on or is it implementation defined or even undefined behavior?
The call to the destructor will happen before the call to the function passed to atexit. From [basic.start.term], p5:
If a call to std::atexit strongly happens before the completion of
the initialization of an object with static storage duration, the call to the destructor for the object is sequenced
before the call to the function passed to std::atexit.

Calling setter once on function static variable

I'm using a function static variable that I want to initialize once by calling a setter:
void foo() {
static Obj obj;
obj.setName("name"); // this should be called once
// use obj
}
I don't want the setter to be called multiple times, also due to multi threading issues and I can't add a constructor to Obj since I don't own the code. So is this reasonable and thread safe:
void foo() {
static Obj obj = []() {
Obj o;
o.setName("name");
return o;
}();
// use obj
}
Yes, it's thread safe. Quoting n3337 - [stmt.dcl]/4, emphasis mine:
...such a variable is initialized 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.
You perform copy initialization from a lambda's return value, but it's immaterial. The paragraph above doesn't constrain the initialization of obj to be value or direct initialization. All forms of initialization are applicable.
And as a side note, if you must contend with such poorly written types, I'd argue your solution is very idiomatic. It doesn't artificially introduce a new named function to perform the initialization. Instead it keeps initialization code localized. That is a good thing in my book.

Referencing a possibly destroyed static object

Assuming I have the following code
Something.hpp
#pragma once
class Something {
public:
static Something& get();
private:
Something();
};
Something.cpp
#include "Something.hpp"
#include <iostream>
using namespace std;
Something& Something::get() {
static Something something;
return something;
}
Something::Something() {
cout << "Something()" << endl;
}
main.cpp
#include <iostream>
using namespace std;
struct SomethingElse {
~SomethingElse() {
Something::get();
cout << "~SomethingElse" << endl;
}
};
void func() {
static SomethingElse something_else;
// do something with something_else
}
int main() {
func();
return 0;
}
Can more than one instance of the Something object ever be created? Does the standard say anything about serializing the destruction of static objects?
Note I am aware the the destruction of file level static variables is undefined when across different translation units, I wanted to know what happens in the case of function scoped static variables (which have the double-checked locking pattern built into the C++ runtime) For the same translation unit case with file level static variables, its easy for the compiler to ensure serialization with construction and destruction based on how the variables are laid out in the code (static), but what happens when the variables are dynamically lazily created when the functions are called?
Note What about for primitive variables? Can we expect them to contain their values till program end? Since they don't need to be destroyed.
Edit
Found this on cppreference.com (http://en.cppreference.com/w/cpp/utility/program/exit)
If the completion of the constructor or dynamic initialization for thread-local or static object A was sequenced-before thread-local or static object B, the completion of the destruction of B is sequenced-before the start of the destruction of A
If this is true then destruction for every static object is serialized? But I also found this
https://isocpp.org/wiki/faq/ctors#construct-on-first-use-v2 which contradicts the standard
The order of construction and destruction of static (and global non-static) objects is well-defined in the C++ specification, for a single translation unit!
If you have multiple translation unit (multiple source files) then the order of construction/destruction between the TUs is not defined.
So the code you show can have undefined behavior.
[stmt.dcl] ¶4
Dynamic initialization of a block-scope variable with static storage duration or thread storage duration is performed the first time control passes through its declaration.
[basic.start.term] ¶1
If the completion of the constructor or dynamic initialization of an object with static storage duration is sequenced before that of another, the completion of the destructor of the second is sequenced before the initiation of the destructor of the first.
¶2
If a function contains a block-scope object of static or thread storage duration that has been destroyed and the function is called during the destruction of an object with static or thread storage duration, the program has undefined behaviour if the flow of control passes through the definition of the previously destroyed block-scope object.
It is in the destructor of SomethingElse that we risk invoking this undefined behaviour:
SomethingElse::~SomethingElse() {
Something::get();
}
If there is an instance of SomethingElse with static storage duration, then there are four possibilities:
The single instance of Something was constructed before the SomethingElse. Its destruction will happen after the SomethingElse, so the behaviour is well defined.
The single instance of Something was constructed after the SomethingElse. Its destruction will have happened before the SomethingElse, so the behaviour is undefined as described above.
The single instance of Something was constructed in a different thread without being synchronized with respect to the construction of the SomethingElse. The destructions may happen concurrently, so the behaviour is undefined.
No instance of Something was yet constructed (i.e. this is the first call to Something::get). In this case, the program calls for the construction of a Something after the SomethingElse, which means the destruction of the Something must happen before the SomethingElse, but since the destruction of the SomethingElse has already commenced, this is a contradiction, and the behaviour is undefined. (Technically, there is a cycle in the "sequenced before" relation.)

c++ destructor getting called 2 times on the same object?

I have the following code snippet:
#include<iostream>
using namespace std;
class Test {
public:
Test() { cout << "Constructor is executed\n"; }
~Test() { cout << "Destructor is executed\n";}
void show() { this->Test::~Test(); }
};
int main() {
Test t;
t.show();
return 0;
}
Here is the output:
Constructor is executed
Destructor is executed
Destructor is executed
Question: If t.show() has already called the destructor on "this" object(i.e. current object), which causes "destructor is executed" to be displayed once, then what causes it to be displayed for the second time? Which object is getting destroyed in that case ?
Automatic variables get destroyed when they go out of scope. Test t is an automatic variable which goes out of scope when main ends. That's the second time the destructor is being called. The first time is through Test::show since the function manually destroys the object pointed to by this.
Since, C++ follows the philosophy of not paying for what you don't use, there isn't a runtime check of any sort before invoking the destructor on automatic variables going out of scope. Of course, what actually happens on the second destructor call is UB. Beware of nasal demons.
Pradhan has given you an easy to understand explanation, I'll share the particular rule that deals with explicit destructor calls on objects with automatic storage duration, found in section 3.8p8 of the Standard:
If a program ends the lifetime of an object of type T with static, thread, or automatic storage duration and if T has a non-trivial destructor, the program must ensure that an object of the original type occupies that same storage location when the implicit destructor call takes place; otherwise the behavior of the program is undefined. This is true even if the block is exited with an exception.
You're violating this rule, so you get undefined behavior.
The "implicit destructor call" is described in 6.7p2:
Variables with automatic storage duration are initialized each time their declaration-statement is executed. Variables with automatic storage duration declared in the block are destroyed on exit from the
block.

A valid singleton Class ?

class Singleton
{
private:
static Singleton s;
Singleton(){}
public:
static Singleton *getInstance()
{
return &s;
}
};
Singleton Singleton::s;
Is this a valid singleton class?
class Singleton
{
private:
static Singleton *m_instance;
Singleton(){}
public:
static Singleton *getInstance()
{
return m_instance;
}
};
Singleton * Singleton::m_instance = new Singleton;
.
class Singleton
{
private:
static Singleton *m_instance;
Singleton(){}
public:
static Singleton *getInstance()
{
if(m_instance == NULL)
{
lock();
if(m_instance == NULL)
m_instance = new Singleton;
unlock();
}
return m_instance;
}
};
Singleton * Singleton::m_instance = NULL;
The three singleton classes above both are thread safe, but they are both prone to "static initialization order fiasco", am I right?
Is this a valid singleton class?
Now, after the edit the answer is yes, it is valid & it is also thread safe since all non-function-scope static variables are constructed before main(), while there is only one active thread.
C++ Standard n3337 § 3.6.2/1 § 3.6.2/2: Initialization of non-local variables
There are two broad classes of named non-local variables: those with
static storage duration (3.7.1) and those with thread storage duration
(3.7.2). Non-local variables with static storage duration are
initialized as a consequence of program initiation. Non-local
variables with thread storage duration are initialized as a
consequence of thread execution. Within each of these phases of initiation, initialization occurs as follows.
Variables with static storage duration (3.7.1) or thread storage
duration (3.7.2) shall be zero-initialized (8.5) before any other
initialization takes place. Constant initialization is performed:
— if each full-expression (including implicit conversions) that
appears in the initializer of a reference with static or thread
storage duration is a constant expression (5.19) and the reference is
bound to an lvalue designating an object with static storage duration
or to a temporary (see 12.2);
— if an object with static or thread storage duration is initialized
by a constructor call, if the constructor is a constexpr constructor,
if all constructor arguments are constant expressions (including
conversions), and if, after function invocation substitution (7.1.5),
every constructor call and full-expression in the mem-initializers and
in the brace-or-equal-initializers for non-static data members is a
constant expression;
— if an object with static or thread storage duration is not
initialized by a constructor call and if every full-expression that
appears in its initializer is a constant expression.
Together, zero-initialization and constant initialization are called
static initialization; all other initial- ization is dynamic
initialization. Static initialization shall be performed before any
dynamic initialization takes place. (...)
C++ Standard n3337 § 6.7/4: Declaration statement
The zero-initialization (8.5) of all block-scope variables with static
storage duration (3.7.1) or thread storage duration (3.7.2) is
performed before any other initialization takes place. Constant
initialization (3.6.2) of a block-scope entity with static storage
duration, if applicable, is performed before its block is first
entered. An implementation is permitted to perform early
initialization of other block-scope variables with static or thread
storage duration under the same conditions that an implementation is
permitted to statically initialize a variable with static or thread
storage duration in namespace scope. Otherwise such a variable is
initialized 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*). (...)
*):
The implementation must not introduce any deadlock around execution of
the initializer.
But it is still prone to static initialization order fiasco. The common way to write getInstance is:
Singleton& getInstance()
{
static Singleton instance;
return instance;
}
This way you can avoid this initialization problem.
Is this a thread-safe singleton class?
In C++11 above code is thread safe. In C++03 you can use
pthread_once
Besides this you should also prevent from copying and assignment:
Singleton( Singleton const&); // Don't Implement
void operator=( Singleton const&); // Don't implement
As far as I can tell, it's thread safe. But it's susceptible to static initialization order fiasco.
If an object tries to access Singleton in it's constructor and that object is constructed during program initialization and this code is in another compilation unit than Singleton, it may or may not crash because Singleton::s may or may not have been initialized yet (because the order of initialization of static objects across compilation units is undefined). Here is an example:
// in another compilation unit, far far away
struct Foo {
Foo() {
Singleton::getInstance();
}
};
Foo foo;
That's the lazy initialised Singleton, yes. It is thread safe under C++11.