I don't find it painful at all. You need to think about the lifetime of your strings. The lifetime is usually convenient to split into two (consecutive) phases: the first phase is when the string gets constructed / modified, and the second phase is the immutable phase up until the string is released again. You'll often have separate string types for these phases: A string builder type for the mutable phase, and a simpler immutable type for the immutable phase.
Often the former will need just a single shared allocation (per thread). That works if you're only ever constructing a single string at a time.
Often the latter won't be dealing with memory management at all. You will often represent it by a plain char pointer and optionally a length field. Management-wise, at most you will need to construct it initially by making an immutable string from the mutable one, and a call to a release function when the string is no longer needed.
The fact that the string isn't modified in the immutable phase makes it trivial to pass it around as an ordinary char pointer (plus optional length), which is as convenient as it gets.
In rare cases you might want to make a hashmap for string interning. I've used interning in a past compiler project, where it was used to collapse identifier strings.
That will probably cover more than 95% of all your string needs. And it's very easy to be vastly more efficient than any from-the-shelf GC'ed string type with this. All you need to invest is to write a little near-boilerplatey code, but it's far from "hard".
aStr("string"); then aMap aFold aConcat, etc, but aAppend(&array,'\0') needs to be done manually if passing to standard str functions. This is so long* or whatever arrays can have the same interface
Nice. I wrote myself up a quick C++ wrapper just now. Will play with this. Intend to use on embedded/bare-metal systems with no C stdlib, so will have to rip out the printfs and the like.
SDS works by allocating a chunk of memory that can fit a header + your string data. The APIs all consume pointers and internally it mutates it's copy of the pointer so it can get at the metadata. So it can be used to generate strings that are passed to other things. I don't think it's easy to use sds operations on other strings in a zero-copy way.
You might look at the Linux version of CFLite, the Apple reference counted C library. Has other things than just strings which would be useful to a C programmer.
Is this a complete drop-in replacement?? If so it could occasionally make my life much easier!