https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118854
--- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> --- #if ( defined(__clang__) && __clang_major__ < 17 ) || ( !defined(__clang__) && defined(__GNUC__) && __GNUC__ < 11 ) // C++20's osyncstream is not supported in GCC < 11 and Clang < 15. It's "experimental" in Clang 15 and 16. Hopefully // Clang 17 will fully support it. This is wrong because the feature works fine in e.g. Clang 14 if you use new libstdc++ headers, and it doesn't work on Clang 19 if you use old libstdc++ headers. What matters is the std::lib implementation, not the compiler version. The right way to do this is: #if __has_include(<syncstream>) # include <syncstream> #endif #ifdef __cpp_lib_syncbuf # define std_osyncstream(s) std::osyncstream( s ) #else # define std_osyncstream(s) ( s ) #endif No fragile list of particular compiler versions and non-portable macros. Anyway, as Andrew correctly said, your pInstance is constructed after gBackgroundThread, which means it's destroyed before gBackgroundThread, so by the time you set _running to false, pInstance is long gone. Before that happens though, the running thread can access the shared_ptr (by calling Resource::instance()) while it's in the middle of running its destructor. That's undefined behaviour. You need to ensure you join the thread before the destructor of _pInstance runs.