On Jul 29, 2024, at 09:18, Dimitry Andric <[email protected]> wrote:

> On 29 Jul 2024, at 18:01, Mark Millard <[email protected]> wrote:
>> 
>> On Jul 29, 2024, at 07:54, Charlie Li <[email protected]> wrote:
>>> ...
> 
>>> While you're talking about std and std.compat, I have a related issue 
>>> whilst working on the www/webkit2-gtk update. They have code that relies on 
>>> a std::pair implementation/ABI that does not work with our base system 
>>> libc++. This is because our base system uses LLVM libc++ ABI version 1, but 
>>> the needed implementation is in ABI version 2, which they have still (even 
>>> in trunk!) not declared stable.
>> 
>> FreeBSD updating its C++ ABI would be a rather major change,
>> or so I would expect. Likely avoided as long as possible?
>> 
>> I wonder what property of std::pair's implementation is at
>> issue for the ABI version distinction(s).
> 
> It's a bit of a historical wart that is hard to get rid of. In FreeBSD we 
> were "too early" and changed our standard C++ library to libc++ before this 
> std::pair trivial copy constructor issue was hashed out in the standards 
> committees.

Looking, I eventually found ( __config ):

#  elif _LIBCPP_ABI_VERSION == 1
. . .
#    if defined(__FreeBSD__)
#      define _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR
#    endif

and ( __utility/pair.h ):

template <class _T1, class _T2>
struct _LIBCPP_TEMPLATE_VIS pair
#if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)
    : private __non_trivially_copyable_base<_T1, _T2>
#endif
{
. . .

So this is not a 1 vs. 2 issue:  it is a FreeBSD-specific odd definition of 1 
that
does not apply to other contexts with _LIBCPP_ABI_VERSION == 1 . I'd not
noticed that in the prior references that I'd run into. (It fits with your 
wording
below, sort of "early 1 vs. late 1" to invent terminology.)

> After it was settled in those committees, libc++ changed its implementation 
> to match, but this actually breaks the ABI!

Sort of "FreeBSD early libc++ ABI 1" vs. "normal late libc++ ABI 1" ABIs.

> For anybody who switched to libc++ after that time, there was no problem 
> using the new ABI, but in FreeBSD we have been stuck with the older 
> interpretation ever since.
> 
> Changing the ABI involves bumping libc++.so to .2, and putting libc++.so.1 
> into a 'compat' package for the sake of old binaries. I had originally wanted 
> to do this for FreeBSD 14 but never got to it, and for some reason upstream 
> is also stalled for years now in bumping their own official ABI version to 2.

If FreeBSD wants an officially stable libc++ without the forced 
__non_trivially_copyable_base<_T1, _T2> then it could:

) have  libc++.so use .2 for libc++ _LIBCPP_ABI_VERSION == 1 without 
_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR defined

) have the  _LIBCPP_ABI_VERSION == 1 with 
_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR defined case for 
libc++.so.1 put into that 'compat' package for the sake of old binaries

There is no reason to need to deal with _LIBCPP_ABI_VERSION == 2 at all for the 
issue at hand.

(Yes, this would mean going forward that for N>= 1, libc++.so.(N+1) would be 
for _LIBCPP_ABI_VERSION == N without the FreeBSD oddity.)

> It would be preferable if upstream libc++ bumps its 'stable' ABI to 2 and 
> starts working on 3 as the then-experimental one, then all downstream 
> consumers can upgrade, leaving all compat crutches behind.
> 

How important is having a numerical match for libc++.so.(_LIBCPP_ABI_VERSION)  
instead of the +/- 1 shifting between the .so and the _LIBCPP_ABI_VERSION ?


===
Mark Millard
marklmi at yahoo.com

Reply via email to