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.)
Related
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.
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.
cin, cout, basic streams related - is it guaranteed anywhere in the standard that these obejcts will be created first and destroyed last?
It would implicate that non-local static objects can rely on them in their constructors and destructors (no ctor race between these objects and the basic streams).
They are guaranteed to be created before any static object declared after including <iostream> and, in any case, before starting main. They are not destroyed during program execution.
Including the header has the effect of declaring a static variable of type ios_base::Init, whose creation ensures that the standard streams are initialised.
If you want the Standardese for this:
C++11 27.4.1 [iostream.objects.overview]/2: The objects are constructed and the associations are established at some time prior to or during the first time an object of class ios_base::Init is constructed, and in any case before the body of main begins execution. The objects are not destroyed during program execution. The results of including <iostream> in a translation unit shall be as if <iostream> defined an instance of ios_base::Init with static storage duration. Similarly, the entire program shall behave as if there were at least one instance of ios_base::Init with static storage duration.
The simple answer to your question is no. As others have pointed out,
there are guarantees for objects defined in translation units
including <iostream>, at least if the object is defined after the
inclusion. But this doesn't always help: you include <iostream> in
the translation unit which defines the constructor, not necessarily in
the one which defines the static variable. So cases like the following
are possible:
file1.hh
class X
{
public:
X();
};
file1.cc
#include "file1.hh"
#include <iostream>
X::X()
{
std::cout << "Coucou, me voila!" << std::endl;
}
file2.cc
#include "file1.hh"
X anX;
In this case, it's quite possible that the constructor of anX be
called before std::cout is constructed.
To be on the safe side: if the constructor of an object which might be
used as a static variable wants to use any of the standard streams, it
should probably declare a local static of type ios_base::Init:
X::X()
{
static ios_base::Init dummyForInitialization;
std::cout << "Coucou, me voila!" << std::endl;
}
If std::cout wasn't already constructed when this constructor is
called, it will be when the static variable is constructed.
I have done little work in multi-threaded environments. So, I need to know whether below class's getInstance function is thread-safe or not. Here is singleton class :
//Singleton class
class S {
// intentionally avoided pointer
static S singleObject;
// Private constructor
s ();
s (S &);
s& operator= (const s&);
public:
// return reference of static object
s& getInstance ()
{
return singleObject;
}
/* Normally with static pointer instance, getInstnace look like as
s& getInstace ()
{
// trying to avoid multiple copies of singleObject
lock_mutex ()
if (singleObject == null)
singleObjecct = new S();
unlock_mutex ();
return *singleObject;
}
*/
};
S S::singleObject;
In getInstance function (un-commented), static object's reference is returned. Does it requires thread-safe mechanism?
In second getInstance (commented), we create the object if singleObject is null. So, it requires a locking mechanism and needs to be synchronized, right?
In getInstance function (un-commented), static object's reference is returned. Does it requires thread-safe mechanism?
As long as you don't access it outside the lifetime of the main function, or modify it when other threads might have unsynchronised access, then it's safe to access from any thread.
If you do access before main starts or after it ends (e.g. from the constructor or destructor of another static object), then there is a danger that it won't have been initialised, or will already have been destroyed, at that point. That is the motivation for "lazy initialisation" such as your second version.
In second getInstance (commented), we create the object if singleObject is null. So, it requires a locking mechanism and needs to be synchronized, right?
Yes, that requires a locking mechanism. For compilers that support the C++11 (or similar) threading model, a simpler way to get lazy initialisation like this is to use a function-static variable, which will be initialised in a thread-safe way the first time it comes into scope:
S& getInstance ()
{
static S singleObject;
return singleObject;
}
This will also avoid the memory leak of your version, but introduces a danger that it might be destroyed before other static objects; therefore, it's not safe to access from a static object's destructor.
In general, static objects in C++ are a minefield of such deathtraps (whether or not you try to wrap them up in some kind of singleton anti-pattern) and are best avoided.
In C++11 you can place static instance inside a static function:
class S
{
private:
S();
S(S const&);
S& operator=(S const&);
public:
static S& getInstance ()
{
static S singleObject;
return singleObject;
}
};
According to paragraph 6.7.4 of the Standard:
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.
Unless you declare getInstance as static you won't be able to call it. This mistake has propagated almost to all replies. Other than this, I can't add anything better to all the answers.
IIRC this is better for more than this reason. It won't initialize (thread safely) until getInstance is called.
-edit- I remember some reasons now. You can't get access unless that method is called. You can call this in other class constructors and wont need to worry if S has been initialized or no. As in the other class may be constructed first in which case a crash or undefined behavior occurs.
//Singleton class
class S {
// intentionally avoided pointer
// Private constructor
s ();
s (S &);
s& operator= (const s&);
public:
// return reference of static object
s& getInstance ()
{
static S singleObject;
return singleObject;
}
};
If I have a class called Test ::
class Test
{
static std::vector<int> staticVector;
};
when does staticVector get constructed and when does it get destructed ?
Is it with the instantiation of the first object of Test class, or just like regular static variables ?
Just to clarify, this question came to my mind after reading Concepts of Programming Languages (Sebesta Ch-5.4.3.1) and it says ::
Note that when the static modifier
appears in the declaration of a
variable in a class definition in C++,
Java and C#, it has nothing to do with
the lifetime of the variable. In that
context, it means the variable is a
class variable, rather than an
instance variable. The multiple use
of a reserved word can be confusing
particularly to those learning the
language.
did you understand? :(
I want to write some text about initializaton too, which i can later link to.
First the list of possibilities.
Namespace Static
Class Static
Local Static
Namespace Static
There are two initialization methods. static (intended to happen at compile time) and dynamic (intended to happen at runtime) initialization.
Static Initialization happens before any dynamic initialization, disregarding of translation unit relations.
Dynamic Initiaization is ordered in a translation unit, while there is no particular order in static initialization. Objects of namespace scope of the same translation unit are dynamically initialized in the order in which their definition appears.
POD type objects that are initialized with constant expressions are statically initialized. Their value can be relied on by any object's dynamic initialization, disregarding of translation unit relations.
If the initialization throws an exception, std::terminate is called.
Examples:
The following program prints A(1) A(2)
struct A {
A(int n) { std::printf(" A(%d) ", n); }
};
A a(1);
A b(2);
And the following, based on the same class, prints A(2) A(1)
extern A a;
A b(2);
A a(1);
Let's pretend there is a translation unit where msg is defined as the following
char const *msg = "abc";
Then the following prints abc. Note that p receives dynamic initialization. But because the static initialization (char const* is a POD type, and "abc" is an address constant expression) of msg happens before that, this is fine, and msg is guaranteed to be correctly initialized.
extern const char *msg;
struct P { P() { std::printf("%s", msg); } };
P p;
Dynamic initialization of an object is not required to happen before main at all costs. The initialization must happen before the first use of an object or function of its translation unit, though. This is important for dynamic loadable libraries.
Class Static
Behave like namespace statics.
There is a bug-report on whether the compiler is allowed to initialize class statics on the first use of a function or object of its translation unit too (after main). The wording in the Standard currently only allows this for namespace scope objects - but it seems it intends to allow this for class scope objects too. Read Objects of Namespace Scope.
For class statics that are member of templates the rule is that they are only initialized if they are ever used. Not using them will not yield to an initialization. Note that in any case, initialization will happen like explained above. Initialization will not be delayed because it's a member of a template.
Local Static
For local statics, special rules happen.
POD type objects initialized with constant expression are initialized before their block in which they are defined is entered.
Other local static objects are initialized at the first time control passes through their definition. Initialization is not considered to be complete when an exception is thrown. The initialization will be tried again the next time.
Example: The following program prints 0 1:
struct C {
C(int n) {
if(n == 0)
throw n;
this->n = n;
}
int n;
};
int f(int n) {
static C c(n);
return c.n;
}
int main() {
try {
f(0);
} catch(int n) {
std::cout << n << " ";
}
f(1); // initializes successfully
std::cout << f(2);
}
In all the above cases, in certain limited cases, for some objects that are not required to be initialized statically, the compiler can statically initialize it, instead of dynamically initializing it. This is a tricky issue, see this answer for a more detailed example.
Also note that the order of destruction is the exact order of the completion of construction of the objects. This is a common and happens in all sort of situations in C++, including in destructing temporaries.
Exactly like regular static (global) variables.
It gets constructed at the same time the global variables get constructed and destructed along with the globals as well.
Simply speaking:
A static member variable is constructed when the global variables are constructed. The construction order of global variables is not defined, but it happens before the main-function is entered.
Destruction happens when global variables are destroyed.
Global variables are destroyed in the reversed order they were constructed; after exiting the main-function.
Regards,
Ovanes
P.S.: I suggest to take a look at C++-Standard, which explains (defines) how and when global or static member variables are constructed or destructed.
P.P.S.: Your code only declares a static member variable, but does not initialize it. To initialize it you must write in one of the compilation units:
std::vector Test::staticVector;
or
std::vector Test::staticVector=std::vector(/* ctor params here */);
Some specific VC++ information in case that's what you're using:
Static class variables construction occurs at same time as other static/global variables.
In windows, the CRT startup function is responsible for this construction.
This is the actual entry point of most programs you compile (it is the function which calls your Main/Winmain function).
In addition, it is responsible for initializing the entire C runtime support (for example you need it to use malloc).
The order of construction is undefined, however when using the microsoft VC compiler the order of construction for basic types will be OK, for example it is legal and safe to write
statics.h:
... MyClass declaration ...
static const int a;
static int b;
static int ar[];
}
statics.cpp:
const int MyClass::a = 2;
int MyClass::b = a+3;
int MyClass::ar[a] = {1,2}