Re:Libc++'s Implementation of std::string
by cryptonector on Friday January 31, 2020 @12:36AM
(#22199379)
Considering jq's libjq's jv[1] C API is CoW and written in C, I'm a bit disinclined to believe that C++ is too weak to express a reasonable CoW API for strings. Instead, I suspect that std::string was too weak a design for that.
The language is too weak to express it safely. CoW on mutable strings in C and C++ by necessity implies safety (or drastically performance-degrading) tradeoffs. By contrast, `jv` types are immutable so they can presumably implement CoW without compromising memory safety or correctness.
Re:Libc++'s Implementation of std::string
by cryptonector on Friday January 31, 2020 @01:07PM
(#22203878)
But `jv` is written in C. It requires that the programmer adhere to a convention, and that is probably what you mean by "too weak" -- and I would agree with that if that is what you mean.
Convention: every malloc() may result in NULL and programs should check for it
Result: many programs forgot
Convention: every non-NULL pointer returned by malloc() should be passed to free() at most once
Result: programs free()'d these pointers twice
Convention: programs should only write to memory addresses [p, p+s) if p is a non-NULL pointer returned by malloc(s), and before calling free(p)
Result: many programs wrote beyond p+s, or wrote to the memory after calling free()
Remind me again, what's a convention?
Re:Libc++'s Implementation of std::string
by cryptonector on Saturday February 01, 2020 @12:53AM
(#22208971)
All APIs have conventions though, and jv's is quite simple. It's very difficult to get it wrong and not crash immediately, though it's easy enough to get it wrong and leak. Having (unfortunately) had to use C a lot, I must say that the jv API is among the nicest I've had the pleasure of using. Sure, it's not Rust, but neither is C++, and yet that's the topic of this thread. But I'd use a jv-like API in C++, and I think that would be peachy.
Re:Libc++'s Implementation of std::string
by zelly on Thursday January 30, 2020 @11:13PM
(#22198974)
const char& c = a.front();
Unfortunately the STL has an overload for the non-const version, which would cause this problem. It's hard to imagine the cases where you'd need a mutable reference to a single character. It can fit into the same register that the reference would live, so even as an immutable reference it doesn't make much sense.That's not an answer. The STL has to have a non-const version that returns some kind of reference. Because C++ strings are mutable and even something like
s[3] = 'h';
involves forming a mutable reference and then assigning its pointee.The way I think about it, to make CoW strings really usable in C++, you basically have to make strings immutable, like many newer languages like Python. That ship has sailed by the time standardization for C++ happened.
There’s nothing stopping you from making const strings. That’s why immutable strings are not added.
Suppose I have a string and I take a reference to a character:
Should the string be copied or not? One might argue, no taking a reference is different from "writing" so no copying, but one might also argue that reference can be used to change the string later, and the string doesn't know when this would happen so it has to pessimistically make a copy.You get bugs if you go with the former, and bad performance if you go with the latter.