1. Introduction
The destruction of variables with static or thread local storage duration can introduce bugs and surprising behavior that is hard to anticipate, and isn’t fully supported across all implementations of C++. Some of the issues include:
- 
     Teardown ordering: the order of destruction across translation units isn’t always the same. 
- 
     Multithreaded teardown: crashes when the main thread is exiting the process and calling destructors while a detached thread is still running and accessing the destructing variables. 
- 
     Shared code that is compiled both as an application and as a library. When library mode is chosen, the same problems as above arise. 
- 
     The operating system can reclaim many resources, particularly memory, faster than the user can anyways. 
- 
     In embedded platforms, it’s often the case that we know that static destructors are never called. It would be useful to avoid emitting them entirely to reduce the amount of generated code. Additionally, providing a way to annotate this property inline in the source code improves readability on these platforms. 
- 
     [basic.start.main] currently says: It is implementation-defined whether a program in a freestanding environment is required to define a This is an unfortunate language mode which we could eventually do away with if we required users of freestanding implementations to annotate this property into their source code.main 
Because of these issues, some implementations provide extensions for their users to disable static or thread local destructors. These extensions are broadly useful, but non-portable, and fragment the language to solve what should be a simple problem. Standardizing these extensions would benefit the entire C++ ecosystem.
2. Proposed Solution
Add new attributes to enable/disable registration of exit-time destructors of static and thread storage duration variables.
The 
struct widget { private : ~ widget (); }; [[ no_destroy ]] widget w ; // not an error! 
Conversely, the 
These attributes currently have an [Implementation] in [Clang]. This proposal is an effort to standardize existing practice.
More background and other possible solutions for this topic can be found in the clang mailing list thread [CFE2016] and [CFE2018]. We considered other alternatives as part of the research for this paper. The Alternatives section provides insights why those solutions aren’t sufficient.
3. Alternatives
Here is a description of different solutions and why they’re inadequate to solve this problem.
3.1. __cxa_atexit 
   Some projects currently override 
3.2. use std :: quick_exit 
   This requires controlling all exit paths from a program, and like the above outright disables destructor calls for all static or thread variables, not ones that the programmer has verified are safe.
3.3. define a type yourself
For instance, one could define 
template < class T > class no_destroy { alignas ( T ) unsigned char data_ [ sizeof ( T )]; public : template < class ... Ts > no_destroy ( Ts && ... ts ) { new ( data_ ) T ( std :: forward < Ts > ( ts )...); } T & get () { return * reinterpret_cast < T *> ( data_ ); } }; no_destroy < widget > my_widget ; 
The class template 
3.4. Use a global reference
For instance:
widget && w = * new widget (); 
Like the above, this can work with variables with automatic storage,
and disables 
4. Future directions
In the future, we could move to make