C++ Logo

std-discussion

Advanced search

Re: CWG 2256 resolution breaks reasonable code

From: Tam S. B. <cpplearner_at_[hidden]>
Date: Fri, 7 Feb 2020 21:11:20 +0000
AFAIK it's fine to use the value of private_constant even outside its lifetime (or at least that's the intent). See [conv.lval]/2.

Though if private_constant is passed by reference (and accessed through the reference), then [conv.lval]/2 is no help.

________________________________________
From: Std-Discussion <std-discussion-bounces_at_[hidden]> on behalf of Christopher Hallock via Std-Discussion <std-discussion_at_[hidden]>
Sent: Friday, February 7, 2020 20:15
To: std-discussion
Cc: Christopher Hallock
Subject: [std-discussion] CWG 2256 resolution breaks reasonable code

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.

Received on 2020-02-07 15:13:58