News for hackers. Stuff that matters.
Re:Libc++'s Implementation of std::string by thedance on Thursday January 30, 2020 @09:59PM (#22198590)
It’s funny that every company gets to the point where they have to have their own std::string. I wonder if Facebook also traces their need back to the time when GNU std::string was copy-on-write and therefore completely useless. Google, I think, can trace their std::string to those dark days. Luckily c++11 effectively outlawed COW string implementations, so nobody need be subject to that horror show again.
Re:Libc++'s Implementation of std::string by faitswulff on Thursday January 30, 2020 @10:13PM (#22198677)
I'm not very good at systems programming, what makes a CoW std::string a bad thing? Memory overhead for a common data structure?
Re:Libc++'s Implementation of std::string by kccqzy on Thursday January 30, 2020 @10:23PM (#22198736)
The language is fundamentally too weak to express the kind of reference and borrowing relationships demanded by CoW.

Suppose I have a string and I take a reference to a character:

    std::string a = f(); // shared
    char& c = a.front();
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.

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.

[1] https://github.com/stedolan/jq/wiki/C-API:-jv

Re:Libc++'s Implementation of std::string by klmr on Friday January 31, 2020 @06:24AM (#22200806)
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.
Re:Libc++'s Implementation of std::string by kccqzy on Friday January 31, 2020 @09:22PM (#22208142)
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.
Re:Libc++'s Implementation of std::string by kccqzy on Friday January 31, 2020 @12:22AM (#22199308)
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.

Re:Libc++'s Implementation of std::string by gumby on Friday January 31, 2020 @12:25AM (#22199326)
There’s nothing stopping you from making const strings. That’s why immutable strings are not added.
Re:Libc++'s Implementation of std::string by gpderetta on Friday January 31, 2020 @07:04AM (#22200979)
s[3] could return a proxy though. Probably still not worth the complexity.
Re:Libc++'s Implementation of std::string by SamReidHughes on Thursday January 30, 2020 @10:36PM (#22198796)
Atomic operations needed on multi-core, and the stuff that leaks a non-const reference to raw memory, like casual read-only use of operator[], .begin(), .end(), forces a copy on shared objects and prevents the object from being shared in the future.
Re:Libc++'s Implementation of std::string by OskarS on Friday January 31, 2020 @03:49AM (#22200129)
In addition to what other people have said, the move semantics introduced in C++11 made a lot of the benefit of CoW moot: the point of CoW is to have a cheap copy operation, but most of those cheap copy operations can be replaced by even cheaper moves, often automatically by the compiler.
Re:Libc++'s Implementation of std::string by thedance on Thursday January 30, 2020 @10:31PM (#22198774)
A copy-on-write string is pretty similar to a shared_ptr to char. Like a shared_ptr, a shared string has to check whether it is the last referent when it goes out of scope. This introduces a point of contention on multi-core systems. A string like the one described in this article might not have to do anything in its destructor, whereas a shared string will need to atomically decrement a reference count. That’s a huge difference in cost.

The benefit of a shared string is you might save some space. That’s fine but I think most programmers today will choose am explicitly shared type when they need it, and a fast string for most cases.

Re:Libc++'s Implementation of std::string by yongjik on Thursday January 30, 2020 @10:22PM (#22198730)
From what I've heard - COW means each string data may be pointed to by multiple objects, potentially being used by different threads. So every string operation requires thread synchronization, which can be quite expensive.
Re:Libc++'s Implementation of std::string by acqq on Friday January 31, 2020 @03:04AM (#22199944)
Does anybody know at which point exactly the GNU std::string implementation changed? Like “since version number N.N of the project X”?
Re:Libc++'s Implementation of std::string by scatters on Friday January 31, 2020 @03:37AM (#22200079)
Since GCC 5.1. The change was and is done in a backward and forward compatible manner, using dual ABI: https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_a...
Re:Libc++'s Implementation of std::string by api on Thursday January 30, 2020 @10:06PM (#22198640)
So your own std::string means you have "arrived?"