3 ms·
Well, libstdc++'s std::string does SSO as depicted in the post. So you're right — 2 out of 3 library vendors manage to do SSO without losing trivial relocatabil
by quuxplusone 2y ago
Well, libstdc++'s std::string does SSO as depicted in the post. So you're right — 2 out of 3 library vendors manage to do SSO without losing trivial relocatability — but consider that 1 in 3 vendors does lose trivial relocatability thereby.
Now consider a type that is like std::string but doesn't do SSO — say, std::vector or std::unique_ptr or even std::shared_ptr. Those types are trivially relocatable on 3 out of 3 vendors, no problem. So I have no problem with the post's example.
Looking forward to part 2!
- aw1621107 2y agoAh, so it does (broadly speaking, at least), and I stand corrected. That was negligent of me to not check. Does libstdc++'s implementation offer advantages that libc++/MSVC's lack? The implementation still looks weird to me, but I've got to be missing something if people far smarter than me decided on that representation.
- quuxplusone 2y agoAs far as I know, libstdc++'s representation has two advantages: First, it simplifies the implementation of `s.data()`, because you hold a pointer that invariably points to the first character of the data. The pointer-less version needs to do a branch there. Compare libstdc++ [1] to libc++ [2]. [1]: https://github.com/gcc-mirror/gcc/blob/065dddc/libstdc++-v3/include/bits/basic_string.h#L225-L228 https://github.com/gcc-mirror/gcc/blob/065dddc/libstdc++-v3/... [2]: https://github.com/llvm/llvm-project/blob/1a96179/libcxx/include/string#L1936-L1938 https://github.com/llvm/llvm-project/blob/1a96179/libcxx/inc... Basically libstdc++ is paying an extra 8 bytes of storage, and losing trivial relocatability, in exchange for one fewer branch every time you access the string's characters. I imagine that the performance impact of that extra branch is tiny, and massively confounded in practice by unrelated factors that are clearly on libc++'s side (e.g. libc++'s SSO buffer is 7 bytes bigger, despite libc++'s string object itself being smaller). But it's there. The second advantage is that libstdc++ already did it that way, and to change it would be an ABI break; so now they're stuck with it. I mean, obviously that's not an "advantage" in the intuitive sense; but it's functionally equivalent to an advantage, in that it's a very strong technical answer to the question "Why doesn't libstdc++ just switch to doing it libc++'s way?"