Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 313
Curious Avatar asked Jan 05 '17 13:01

Curious


1 Answers

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.

like image 149
Some programmer dude Avatar answered Oct 30 '22 06:10

Some programmer dude