C++ Logo

STD-DISCUSSION

Advanced search

Subject: CWG 2256 resolution breaks reasonable code
From: Christopher Hallock (christopherhallock_at_[hidden])
Date: 2020-02-07 14:15:45


The resolution to CWG 2256
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1358r0.html#2256>
makes std::exit() (including the implicit call after main()) end the
lifetime of *all* static objects constructed thus far instead of only those
with non-trivial destructors. But this breaks reasonable programs. For
example:

widget.h:
class widget { /*...*/ public: ~widget(); };

widget.cpp:
#include "widget.h"
constexpr int private_constant = 5;
widget::~widget() { /*uses private_constant*/ }

main.cpp:
#include "widget.h"
const widget default_widget(/*...*/);
int main() { /*...*/ }

The destruction of default_widget triggers UB if it happens to be ordered
after the destruction of private_constant. Such an ordering is permitted
because the two objects are in different translation units and because "if
an object is initialized statically, the object is destroyed in the same
order as if the object was dynamically initialized" ([basic.start.term]/3
<https://timsong-cpp.github.io/cppwp/basic.start#term-3.sentence-3>). I
submit that std::exit() shouldn't destroy trivially-destructable
static-storage objects at all, or at least not clearly-innocuous objects
like constexpr integral variables in namespace scope.



STD-DISCUSSION list run by std-discussion-owner@lists.isocpp.org

Older Archives on Google Groups