public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/61991] New: Destructors not always called for statically initialized thread_local objects
@ 2014-08-01 17:16 scovich at gmail dot com
  2015-07-10 13:53 ` [Bug c++/61991] " scovich at gmail dot com
  2021-08-22 23:18 ` pinskia at gcc dot gnu.org
  0 siblings, 2 replies; 3+ messages in thread
From: scovich at gmail dot com @ 2014-08-01 17:16 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61991

            Bug ID: 61991
           Summary: Destructors not always called for statically
                    initialized thread_local objects
           Product: gcc
           Version: 4.9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: scovich at gmail dot com

If a thread_local object is statically initialized---trivial or constexpr
constructor---but has a non-trivial destructor, the destructor will only run if
some *other* thread_local object needs dynamic initialization *and* if at least
one such object is accessed by the thread during its lifetime. Accessing
members of the object itself does nothing, because it is statically
initialized.

Example:

#include <cstdio>
static thread_local struct X { 
    ~X() { 
        printf("bye!\n"); 
    }
} x;
static thread_local int y = printf("initialized y\n");
int main() { 
   //printf("%d\n", y);
}

Compiling the above with `g++ -std=gnu++11 bug.cpp' gives an executable that
produces no output when run. 

Uncomment the printf in main() and recompile, and the resulting executable
prints:

initialized y
14
bye!

The only hint of trouble at compile time is that the compiler may warn about an
unused variable. However, that warning only comes if the offending object is
never accessed otherwise (perhaps because it is an exit guard of some type),
has static storage class, *and* no other dynamic thread_local storage exists...
an unlikely combination.

Looking at the assembly code output, the problem is obvious: X::~X is only
registered with __cxa_thread_exit if __tls_init is called, and the latter is
only called if the thread accesses a TLS object that needs dynamic
initialization. 

Under Cygwin, I hit the further problem that __tls_init doesn't even contain
the any calls to __cxa_thread_exit. That's probably a separate bug, though, and
I don't know whose problem it might be.

If there's no easy fix, might I suggest a loud warning somewhere in the docs
might be appropriate so people have a way to know about the limitation? I tried
searching for this online, but Google didn't turn anything up.

(Discovered in 4.8.3, still there in 4.9.0, and given the nature of the bug I
suspect it's in more recent versions, too).


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Bug c++/61991] Destructors not always called for statically initialized thread_local objects
  2014-08-01 17:16 [Bug c++/61991] New: Destructors not always called for statically initialized thread_local objects scovich at gmail dot com
@ 2015-07-10 13:53 ` scovich at gmail dot com
  2021-08-22 23:18 ` pinskia at gcc dot gnu.org
  1 sibling, 0 replies; 3+ messages in thread
From: scovich at gmail dot com @ 2015-07-10 13:53 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61991

--- Comment #1 from Ryan Johnson <scovich at gmail dot com> ---
C++14 (N3652 [1]) specifically alters the Standard to state that a thread_local
object with static or constexpr initialization may have a non-trivial
destructor (implying that such a destructor should actually run):

> Variables with static storage duration (3.7.1) or thread storage duration
> (3.7.2) shall be zero-initialized (8.5) before any other initialization takes
> place. A constant initializer for an object o is an expression that is a
> constant expression, except that it may also invoke constexpr constructors for
> o and its subobjects even if those objects are of non-literal class types
> [ Note: such a class may have a non-trivial destructor ].

[1] https://isocpp.org/files/papers/N3652.html


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Bug c++/61991] Destructors not always called for statically initialized thread_local objects
  2014-08-01 17:16 [Bug c++/61991] New: Destructors not always called for statically initialized thread_local objects scovich at gmail dot com
  2015-07-10 13:53 ` [Bug c++/61991] " scovich at gmail dot com
@ 2021-08-22 23:18 ` pinskia at gcc dot gnu.org
  1 sibling, 0 replies; 3+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-08-22 23:18 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61991

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
GCC, clang and ICC all have this same behavior in that if y is not used, the y
is not initialized or deconstructed.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-08-22 23:18 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-01 17:16 [Bug c++/61991] New: Destructors not always called for statically initialized thread_local objects scovich at gmail dot com
2015-07-10 13:53 ` [Bug c++/61991] " scovich at gmail dot com
2021-08-22 23:18 ` pinskia at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).