On Wed, Jul 17, 2024 at 2:01 PM Hans via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
On 14/07/2024 01:10, Thiago Macieira via Std-Proposals wrote:
> You're asking that the Standard Library add a new set of classes that promises
> stability. But you have not provided any evidence or method by which such new
> classes would be more stable than the current classes are right now and have
> been for two decades.

Existing classes are defacto stable: not because they are defined to be
stable, but because we decided changing them would be worse than leaving
them as-is. Using such a class in a public interface works...
sometimes... and could conceivably stop working tomorrow, because no
guarantee of it remaining stable indefinitely was ever provided.

The proposed stable classes aren't stable thanks to any deep magic in
their implementation, but because the standard formally declares them to
be stable (and provides the conditions for making that happen). You can
use them in a public interface, and code written a century from now will
still correctly interoperate with it.
 
[...] If I switch msvc build mode from
release to debug, sizeof (std::string) changes from 32 bytes to 40
bytes. [...] there is no agreement
between compilers on what an std::string looks like, see
https://devblogs.microsoft.com/oldnewthing/20240510-00/?p=109742
 
[...] std::string
could probably do better on all platforms (by leveraging more space for
the SSO buffer).

So, what would your `std::stable::string` actually look like? Would it "do better" by using more space for the SSO buffer? Would it try to futureproof itself by not using an SSO buffer at all?
Would it be guaranteed to have the same ABI on both Clang and GCC, both libc++ and libstdc++? Or would it still be incompatible between those two?
Certainly it must be incompatible between libraries built with the Itanium ABI and libraries built with the MS ABI, because they don't even agree on which register to pass the `this` pointer in. Which is rather important, for a type with a non-trivial destructor (which needs a `this` pointer!).

I think all of the hypothetical advantages of a `std::stable::string` could equally well be achieved with a `hans::stable::string`. You could write that class, put it up on GitHub (or whatever), and promise never to change its ABI ever. (Plus whatever other promises you think `std::stable` should provide.) Then, if people believe your promise — for the sake of argument let's assume that they will believe it — then they should be willing to use your type in their library ABIs.
I think actually trying this exercise will cause you to discover some practical difficulties with it.

It's a first basic attempt at defining what the requirements on stable
types would be, and I acknowledge that it requires refinement. I
deferred that work because it is a lot of effort, and I wanted to make
sure it would be necessary before committing to it.

I think writing your own `hans::stable::string` would help to refine your ideas. Writing forces you to think about considerations that might otherwise be handwaved or not-even-realized.
 
> In the std::stable namespace section, you say "committee-supplied ABI" but
> that's woefully short of details. Is it just a description of the class layout
> in the form of a C structure (and hence the "standard layout" requirement from
> above")? If so, say so. For me, ABI implies much more, including the size and
> alignment of types, which the committee could never provide for all possible
> target architectures.

It's in the form of a C structure. The ABI that you talk about here is
the platform ABI, which is out of scope for both this paper and the
standard, for the reason that you give.

Surely the ABI of a C++ type also includes how it's passed to functions and returned from functions. (Itanium calls that its "triviality for purposes of calls.")
ABI is much much more than just its memory footprint.

HTH,
Arthur