Earlier quoted context omitted.
The right way to do this would be: typedef struct sds { char *s; } sds; Now you get type safety: you can't accidentally pass a plain 'ole C string to an sds function. But you do need to access the 's' field to get the C string for passing to non-sds functions.
This is fine, but it somewhat defeats the purpose of the opaquely prefixed header. I think the idea is just to be able to treat an SDS like a normal string. Unfortunately, there's no way to have that property not be commutative in C.
Simple Dynamic Strings library for C, compatible with null-terminated strings
51–60 of 85 posts
Re: Simple Dynamic Strings library for C, compatible with null-terminated strings
#52Re: Simple Dynamic Strings library for C, compatible with null-terminated strings
#53I tend to use libdjb[0] if I need to use strings in C. Is this library significantly easier? [0] http://www.fefe.de/djb/
from the top of that page: (Note: This has not been touched since 2000, use [2] instead) [1] https://www.fefe.de/libowfat/
Re: Simple Dynamic Strings library for C, compatible with null-terminated strings
#54Hi, author here. May make sense to make SDS in perspective given a few comments I'm reading here. 1. Yep, more than "strings" SDS may be consider a library for dynamic buffers, especially from people coming from C++ or higher level languages. However I think that for C, it makes sense to provide a very low level thing like that. 2. In practice, if you see how SDS is used (extensively) inside Redis, it normally models…
C has always badly needed built-in strings (and arrays with size info, generally).
To save a byte, C designers committed The Most Expensive One-byte Mistake https://queue.acm.org/detail.cfm?id=2010365
Re: Simple Dynamic Strings library for C, compatible with null-terminated strings
#55Earlier quoted context omitted.
Exactly. You should not name a buffer lib "string", when it does not support the basic unicode operations: case fold, normalize => compare, search. In utf-8 of course. I'm also missing stack allocation support, needed for fast short strings. It should be even included in sdsnew, for len < 128.
How do you implement stack allocation support inside a C library function? How is de-allocation expressed?
Re: Simple Dynamic Strings library for C, compatible with null-terminated strings
#56UTF support?
Exactly. You should not name a buffer lib "string", when it does not support the basic unicode operations: case fold, normalize => compare, search. In utf-8 of course. I'm also missing stack allocation support, needed for fast short strings. It should be even included in sdsnew, for len < 128.
Re: Simple Dynamic Strings library for C, compatible with null-terminated strings
#57Earlier quoted context omitted.
I think you're missing the point here, the conversion function is trivially inlinable: char* sds_cstr(sds *str){ return &str[0]; //you could probably just cast too } The other posters solution is actually not equivalent in this way (his sds is convertable to char* instead of sds*).
Even an inlined function only has value if our goal is to open the door to implementation changes in the future. But because the current implementation is zero-cost (an inlined no-op), any behavioral change will necessary compromise performance. Otherwise (if we want to retain the zero-cost guarantee of converting to a C string), directly accessing the member variable is: functionally equivalent, simpler, more concis…
With that said, I agree that the additional verbosity is a significant drawback, and I can understand going with the slightly-less-safe option for that reason alone.
Re: Simple Dynamic Strings library for C, compatible with null-terminated strings
#58Hi, author here. May make sense to make SDS in perspective given a few comments I'm reading here. 1. Yep, more than "strings" SDS may be consider a library for dynamic buffers, especially from people coming from C++ or higher level languages. However I think that for C, it makes sense to provide a very low level thing like that. 2. In practice, if you see how SDS is used (extensively) inside Redis, it normally models…
> show how much you can easily improve C, with little work, and how many unsafe things in C are about lack of abstractions C has always badly needed built-in strings (and arrays with size info, generally). To save a byte, C designers committed The Most Expensive One-byte Mistake https://queue.acm.org/detail.cfm?id=2010365
Re: Simple Dynamic Strings library for C, compatible with null-terminated strings
#59Earlier quoted context omitted.
Even an inlined function only has value if our goal is to open the door to implementation changes in the future. But because the current implementation is zero-cost (an inlined no-op), any behavioral change will necessary compromise performance. Otherwise (if we want to retain the zero-cost guarantee of converting to a C string), directly accessing the member variable is: functionally equivalent, simpler, more concis…
I actually prefer the inline function here (while making the member char* private when compiling as C++), since that mostly prevents assignment to the member variable in settings where that would not be a valid operation. With that said, I agree that the additional verbosity is a significant drawback, and I can understand going with the slightly-less-safe option for that reason alone.
However: If we open the discussion up to C++, then this is pretty easy to solve without any real syntactic or performance compromise: we can make a class/struct which defines implicit conversions to C strings, and disables any implicit conversions from C strings.
Re: Simple Dynamic Strings library for C, compatible with null-terminated strings
#60https://sourceforge.net/p/joe-editor/mercurial/ci/default/tr...
I also have NULL terminated arrays of strings, like arguments lists:
https://sourceforge.net/p/joe-editor/mercurial/ci/default/tr...
It's set up so that you could make a dynamic arrays of any types by copying the header and source files, but changing a few constants and providing comparison and duplication functions for the elements involved. It's like manual template instantiation.
Of course this is prone to memory leaks, same as sds. But there is branch here:
https://sourceforge.net/p/joe-editor/mercurial/ci/coroutine/...
In this version, all strings are allocated on an obstack. Space for temporary strings is automatically reclaimed when you return to the top level.
You can mark a string as permanent, then it will not be reclaimed, and instead has to be explicitly freed. So you can still have memory leaks but less likely, and also you could have accidental automatic freeing, but a lot of explicit frees are eliminated.
C++ strings are better... except that I have my own library for them also because I hate not being able to return NULL to indicate a failure. This is called the semi-predicate capability of C strings, and is easy to have in C++ with a different library.