On Sat, 12 Apr 2025, Jeremy Drake via Cygwin-apps wrote: > On Sat, 12 Apr 2025, Jeremy Drake via Cygwin-apps wrote: > > > On Sun, 13 Apr 2025, Takashi Yano via Cygwin-apps wrote: > > > > > > Yes. However, see my previous mail for the strange issue I ran into > > > > trying to do this (strange because it works fine on MSYS2 but fails on > > > > Cygwin) > > > > > > The same happens for me as well... > > > > Maybe you'll have some luck debugging it. I really don't use Cygwin (the > > software distribution), but rather MSYS2 (and indirectly Cygwin the DLL as > > msys2-runtime). The fact that this doesn't happen on MSYS2 is very > > strange and probably a good start to trying to narrow it down. > > OK, here's my theory: > #12 0x00007ffda3510f9a in free ( > p=0x100557010 <std::basic_string<char, std::char_traits<char>, > std::allocator<char> >::_Rep::_S_empty_rep_storage>) > > p is in the address space of the exe (0x00000001004e210e) , not > cygstdc++-6 (0x00000003fb09c960). So it seems that it inlined the > _S_empty_rep_storage[] when it shouldn't have. Looking at > /usr/lib/gcc/13.3.0/include/c++/bits/basic_string.tcc (on MSYS2): > > // Inhibit implicit instantiations for required instantiations, > // which are defined via explicit instantiations elsewhere. > #if _GLIBCXX_EXTERN_TEMPLATE > // The explicit instantiation definitions in src/c++11/string-inst.cc and > // src/c++17/string-inst.cc only instantiate the members required for C++17 > // and earlier standards (so not C++20's starts_with and ends_with). > // Suppress the explicit instantiation declarations for C++20, so C++20 > // code will implicitly instantiate std::string and std::wstring as needed. > # if __cplusplus <= 201703L && _GLIBCXX_EXTERN_TEMPLATE > 0 > extern template class basic_string<char>; > # elif ! _GLIBCXX_USE_CXX11_ABI > // Still need to prevent implicit instantiation of the COW empty rep, > // to ensure the definition in libstdc++.so is unique (PR 86138). > extern template basic_string<char>::size_type > basic_string<char>::_Rep::_S_empty_rep_storage[]; > # elif _GLIBCXX_EXTERN_TEMPLATE > 0 > // Export _M_replace_cold even for C++20. > extern template void > basic_string<char>::_M_replace_cold(char *, size_type, const char*, > const size_type, const size_type); > # endif > > > You could check what some of these defines are on Cygwin, but I'm guessing > https://cygwin.com/cgit/cygwin-packages/gcc/tree/gcc.cygport?h=main&id=3b18f0b66c716fd70492f55ebebd5680a611739c#n171 > (--with-default-libstdcxx-abi=gcc4-compatible). MSYS2 does not do this, > it's small enough that we can plausibly rebuild every MSYS2-packages > package that links against msys-stdc++-6.dll for an ABI break. Cygwin > doesn't have that luxury, since it could be that 3rd parties are shipping > Cygwin binaries. >
# define _GLIBCXX_EXTERN_TEMPLATE 1 Below differs from MSYS2 #ifndef _GLIBCXX_USE_CXX11_ABI # define _GLIBCXX_USE_CXX11_ABI 0 #endif Maybe setting -DCMAKE_CXX_STANDARD=20 would work around this? It would at least take a different path in that if/elif block in basic_string. But I think we need to figure out why the extern template isn't working regardless.