This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Potential bug about the order of destructors of static objects and atexit() callbacks in C++?
- From: Markus Trippelsdorf <markus at trippelsdorf dot de>
- To: lh mouse <lh_mouse at 126 dot com>
- Cc: gcc <gcc at gcc dot gnu dot org>
- Date: Mon, 1 Aug 2016 12:28:49 +0200
- Subject: Re: Potential bug about the order of destructors of static objects and atexit() callbacks in C++?
- Authentication-results: sourceware.org; auth=none
- References: <418d0e36.307375.156459ac339.Coremail.lh_mouse@126.com>
On 2016.08.01 at 18:16 +0800, lh mouse wrote:
> Hello GCC developers,
>
> Reading the ISO C++ standard,
> > 3.6.4 Termination [basic.start.term]
> > 3 If the completion of the initialization of an object with
> > static storage duration is sequenced before a call to std::atexit
> > (see <cstdlib>, 18.5), the call to the function passed to std::atexit
> > is sequenced before the call to the destructor for the object. ...
>
> Notwithstanding the vagueness of 'the completion of the initialization of an object',
> the following program:
>
> #include <cstdlib>
> #include <cstdio>
>
> enum class state {
> null,
> initialized,
> destroyed,
> };
>
> extern void broken_atexit();
>
> struct global_data {
> state s;
>
> global_data()
> : s(state::null)
> {
> std::puts("delegated constructor");
> }
> global_data(int)
> : global_data()
> {
> s = state::initialized;
> std::atexit(&broken_atexit);
> std::puts("delegating constructor");
> }
> ~global_data(){
> s = state::destroyed;
> }
> } data(1);
>
> void broken_atexit(){
> if(data.s == state::destroyed){
> std::puts("attempt to use a destroyed object?");
> std::abort();
> }
> std::puts("okay");
> }
>
> int main(){
> }
>
> , when compiled with GCC, results in use of a destroyed object:
>
> lh_mouse@lhmouse-dev:~$ g++ test.cc -std=c++11
> lh_mouse@lhmouse-dev:~$ ./a.out
> delegated constructor
> delegating constructor
> attempt to use a destroyed object?
> Aborted
> lh_mouse@lhmouse-dev:~$
>
> The reason of this problem is that GCC front-end registers the dtor after
> the delegating constructor returns, which is invoked before the other
> callback registered inside the delegating constructor body.
>
> The problem would be gone only if the GCC front-end registers the dtor after
> the delegated constructor returns.
>
> Is this a GCC bug?
I don't think so. All compilers (clang, icc, visual C++) behave the
same.
Also these kinds of questions regarding the C++ standard should be asked
on a more appropriate forum like stackoverflow.com or the ISO C++ group:
https://groups.google.com/a/isocpp.org/forum/?fromgroups#!forum/std-discussion
--
Markus