This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/72768] New: Potential bug about the order of destructors of static objects and atexit() callbacks in C++?
- From: "lh_mouse at 126 dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Mon, 01 Aug 2016 14:56:46 +0000
- Subject: [Bug c++/72768] New: Potential bug about the order of destructors of static objects and atexit() callbacks in C++?
- Auto-submitted: auto-generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72768
Bug ID: 72768
Summary: Potential bug about the order of destructors of static
objects and atexit() callbacks in C++?
Product: gcc
Version: 6.1.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: lh_mouse at 126 dot com
Target Milestone: ---
Created attachment 39040
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=39040&action=edit
The testcase in question.
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?