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.

Reply via email to