Live data from Hacker News

Simple Dynamic Strings library for C, compatible with null-terminated strings

github.com

51–60 of 85 posts

Re: Simple Dynamic Strings library for C, compatible with null-terminated strings

#51
post #45

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.

Yeah, but almost perfect ergonomics is good enough, and type safety >> ergonomics.

Re: Simple Dynamic Strings library for C, compatible with null-terminated strings

#53
post #7

I 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/

Also, in general, you can expect that if someone links to a site, they will have read the first few lines of that page, and the people who later follow that link will read them too.

Re: Simple Dynamic Strings library for C, compatible with null-terminated strings

#54
post #24

Hi, 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

#55
post #49
post #20

Earlier 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?

alloca()?

Re: Simple Dynamic Strings library for C, compatible with null-terminated strings

#56
post #20

UTF 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.

For stack allocation might as well just make a fixed sized char array then. sds by its design seems meant for heap strings (d in the name means dynamic).

Re: Simple Dynamic Strings library for C, compatible with null-terminated strings

#57

Earlier 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…

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.

Re: Simple Dynamic Strings library for C, compatible with null-terminated strings

#58
post #24

Hi, 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

Thanks for the link. Great analysis of a real sliding-doors moment.

Re: Simple Dynamic Strings library for C, compatible with null-terminated strings

#59

Earlier 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.

Ah, that’s a good point. I’m a fan of extra safety, though we’d need to make a few extra changes to get around C’s lack of private variables: We could make the internal member instead a size_t, and cast to pointer form when needed inside the library or when converting via this inline function (which is still a no-op in terms of performance). The only major downside then remaining is perhaps syntax/verbosity, which IMO is secondary to safety.

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

#60
My version of this (from 1992!) is here:

https://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.

Post reply on HN