HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
antirez
sds
C2014–2026
antirez / sds

sds

Simple Dynamic Strings library for C

50Distinct people
67Mentions
0Explicit recommenders
5.6KGitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

Simple Dynamic Strings library for C

GitHub

Where it is used

No documented product use was verified in the last source check.

What people are saying

No recommendation phrase was found in the indexed comments.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

No other repository is repeatedly linked in the same discussions.

This week on Hacker News

Nov 8–Nov 15 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/15/2026, 2:59:58 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year67 dated mentions

Observed mentions: 2014-02-06 14:59:52 UTC to 2026-10-15 10:38:01 UTC.

0510152014-01-01 00:00:00 UTC to 2015-01-01 00:00:00 UTC (exclusive): 5 mentions; 1 submissions, 4 comments20142015-01-01 00:00:00 UTC to 2016-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2016-01-01 00:00:00 UTC to 2017-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2017-01-01 00:00:00 UTC to 2018-01-01 00:00:00 UTC (exclusive): 4 mentions; 1 submissions, 3 comments2018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 7 mentions; 1 submissions, 6 comments2019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 10 mentions; 1 submissions, 9 comments2020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 3 mentions; 0 submissions, 3 comments20202021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 13 mentions; 1 submissions, 12 comments2022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 5 mentions; 0 submissions, 5 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 5 mentions; 0 submissions, 5 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 4 mentions; 0 submissions, 4 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 4 mentions; 2 submissions, 2 comments2026-01-01 00:00:00 UTC to 2027-01-01 00:00:00 UTC (exclusive): 4 mentions; 0 submissions, 4 comments. Incomplete calendar period.2026*

* An incomplete calendar period is marked with an outlined bar. Its count is not directly comparable with a full period.

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20142014-01-01 00:00:00 UTC2015-01-01 00:00:00 UTC514
20152015-01-01 00:00:00 UTC2016-01-01 00:00:00 UTC202
20162016-01-01 00:00:00 UTC2017-01-01 00:00:00 UTC101
20172017-01-01 00:00:00 UTC2018-01-01 00:00:00 UTC413
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC716
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC1019
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC303
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC13112
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC505
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC505
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC404
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC422
2026 (partial)2026-01-01 00:00:00 UTC2027-01-01 00:00:00 UTC404

From the project README

An excerpt from the repository, fetched Nov 13, 2026.

Read the project’s introduction
Simple Dynamic Strings Notes about version 2: this is an updated version of SDS in an attempt to finally unify Redis, Disque, Hiredis, and the stand alone SDS versions. This version is NOT binary compatible* with SDS verison 1, but the API is 99% compatible so switching to the new lib should be trivial. Note that this version of SDS may be a slower with certain workloads, but uses less memory compared to V1 since header size is dynamic and depends to the string to alloc. Moreover it includes a few more API functions, notably sdscatfmt which is a faster version of sdscatprintf that can be used for the simpler cases in order to avoid the libc printf family functions performance penalty. How SDS strings work SDS is a string library for C designed to augment the limited libc string handling functionalities by adding heap allocated strings that are: Simpler to use. Binary safe. Computationally more efficient. But yet... Compatible with normal C string functions. This is achieved using an alternative design in which instead of using a C structure to represent a string, we use a binary prefix that is stored before the actual pointer to the string that is returned by SDS to the user. +--------+-------------------------------+-----------+ | Header | Binary safe C alike string... | Null term | +--------+-------------------------------+-----------+ | `-> Pointer returned to the user. Because of meta data stored before the actual returned pointer as a prefix, and because of every SDS string implicitly adding a null term at the end of the string regardless of the actual content of the string, SDS strings work well together with C strings and the user is free to use them interchangeably with other std C string functions that access the string in read-only. SDS was a C string I developed in the past for my everyday C programming needs, later it was moved into Redis where it is used extensively and where it was modified in order to be suitable for high performance operations. Now it was extracted from Redis and forked as a stand alone project. Because of its many years life inside Redis, SDS provides both higher level functions for easy strings manipulation in C, but also a set of low level functions that make it possible to write high performance code without paying a penalty for using an higher level string library. Advantages and disadvantages of SDS Normally dynamic string libraries for C are implemented using a structure that defines the string. The structure has a pointer field that is managed by the string function, so it looks like this: struct yourAverageStringLibrary { char *buf; size_t len; ... possibly more fields here ... }; SDS strings as already mentioned don't follow this schema, and are instead a single allocation with a prefix that lives before the address actually returned for the string. There are advantages and disadvantages with this approach over the traditional approach: Disadvantage #1: many functions return the new string as value, since sometimes SDS requires to create a new string with more space, so the most SDS API calls look like this: s = sdscat(s,"Some more data"); As you can see s is used as input for sdscat but is also set to the value returned by the SDS API call, since we are not sure if the call modified the SDS string we passed or allocated a new one. Not remembering to assign back the return value of sdscat or similar functions to the variable holding the SDS string will result in a bug. Disadvantage #2: if an SDS string is shared in different places in your program you have to modify all the references when you modify the string. However most of the times when you need to share SDS strings it is much better to encapsulate them into structures with a reference count otherwise it is too easy to incur into memory leaks. Advantage #1: you can pass SDS strings to functions designed for C functions without accessing a struct member or calling a function, like this: printf("%s\n", sds_string); In most other libraries this will be something like: printf("%s\n", string->buf); Or: printf("%s\n", getStringPointer(string)); Advantage #2: accessing individual chars is straightforward. C is a low level language so this is an important operation in many programs. With SDS strings accessing individual chars is very natural: printf("%c %c\n", s[0], s[1]); With other libraries your best chance is to assign string->buf (or call the function to get the string pointer) to a char pointer and work with this. However since the other libraries may reallocate the buffer implicitly every time you call a function that may modify the string you have to get a reference to the buffer again. Advantage #3: single allocation has better cache locality. Usually when you access a string created by a string library using a structure, you have two different allocations for the structure representing the string, and the actual buffer holding the string. Over the time the buffer is reallocated, and it is likely that it ends in a totally different part of memory compared to the structure itself. Since modern programs performances are often dominated by cache misses, SDS may perform better in many workloads. SDS basics The type of SDS strings is just the char pointer char *. However SDS defines an sds type as alias of char * in its header file: you should use the sds type in order to make sure you remember that a given variable in your program holds an SDS string and not a C string, however this is not mandatory. This is the simplest SDS program you can write that does something: sds mystring = sdsnew("Hello World!"); printf("%s\n", mystring); sdsfree(mystring); output> Hello World! The above small program already shows a few important things about SDS: SDS strings are created, and heap allocated, via the sdsnew() function, or other similar functions that we'll see in a moment. SDS strings can be passed to printf() like any other C string. SDS strings require to be freed
Read the full README on GitHub

What Hacker News says

13 sources
I would rather use C++, however if I really must write C, then a string handling library like the SDS from Redis project is a must. https://github.com/antirez/sds Naturally turning on all security features of the C compiler being used, warnings, warnings as errors, static analysers, FORTIFY like libraries, the whole package. And like almost everyone else, I end up having my occasional segfault regardless of the amount of precautions taken, because I am not elite enough.
In strcpy: A niche function you don't need
I agree that the email does not set out a solid argument and the "angry technical shlock" is unclear - that's what I was getting at by "aggressively worded". I think there exists a solid and reasonable argument along these lines, even if Linus did not phrase it, though, which is what I'm getting at. (And I suspect Linus and others do believe that argument, even if they're not good at communicating it, so it would be worth engaging it.) It's true that you could write C++ without exception handling, and that you get to choose the abstractions. But it matters what the language makes easy for you - what is idiomatic and conventional in the language - what programmers who use that language have come to expect their libraries to do. Otherwise you could just say that we can solve our string problems in C without switching languages by simply usi
Read the rest
ng length-prefixed strings and buffers and not relying on NUL termination. After all, the kernel doesn't use a userspace standard library, and even in userspace there are string-handling libraries in C that avoid those problems (e.g., http://bstring.sourceforge.net/ or https://github.com/antirez/sds). But the fact remains that the kernel has its own implementations of strcat and sprintf nonetheless (in the lib/ directory), simply because C programmers expect them. And people call NUL-terminated strings "C strings" and length-prefixed strings "Pascal strings," even though you can do length-prefixed strings just in C and NUL-terminated strings just fine in Pascal. It is very hard to write abstractions in C++ that work the way the abstractions in Rust work and are still natural and easy to use. No one is disputing they're possible to write. But if you look at the blog post I linked, it demonstrates that even with the benefit of decades of experience in C++ and knowledge of what Rust is doing, and even with additional language features, and even with the input of people who did in fact choose their abstractions (std::string_view was based on libraries local to Google, LLVM, and Bloomberg), you still do not get the level of safety that the equivalent Rust feature has. Concretely, 1. C++ has language-level features (most importantly, try/catch/finally) that make error handling via exceptions easy and natural to use. Rust has language-level features (most importantly, pattern matching on sum types) that make error handling via a result type easy and natural to use. You can of course choose not to use exceptions, but you're giving up a good language feature and you don't have language support for the thing you want to do instead. This is much like saying "Don't like NUL-terminated strings? Don't use them" - technically true, but have fun avoiding string literals. 2. This is not a general-purpose tirade against abstraction. It is a very targeted tirade against implicit conversions to heap-allocated types, which are natural and idiomatic in C++. See my comment https://news.ycombinator.com/item?id=27749301 elsewhere in this thread for details on exactly what Linus is objecting to and why it is entirely reasonable for a kernel to object to it. Again, you could certainly decide to avoid implicit allocations in your nonstandard library, but it is not idiomatic C++. 3. C++'s object model is legitimately quite complex, involving things like multiple inheritance, partially-constructed objects during the constructor, and phrases like "morally virtual base". It works - there's definitely a lot of working C++ in the world - but that level of complexity isn't needed by the kernel, and (certainly in my personal experience) it's easy to get into deeply confusing situations. The kernel also cares about things like fitting objects into cachelines. The kernel doesn't need multiple inheritance with the ability to have different offsets into an object depending on what pointer type you're using, but it does need the ability to specify that objects implement multiple interfaces that carry no data (what the kernel calls "operations structures," and what Rust calls "traits"). In C++, the only mechanism the language gives you for this is multiple inheritance. There are use cases where full multiple inheritance is useful, and C++ is preferable to Rust for such cases. The Linux kernel is not one of them. It's true that you can do all the things Rust can do in C++ if you try hard enough. But I'd reiterate the point which you made clearly, that human beings simply do not seem able to write flawless C in practice, even though it is theoretically possible, because it is simply not idiomatic. From the blog post I linked, it seems like there's no reason to expect that asking humans to write flawless and unidiomatic C++ will work out any better.
In Linux Rust Support
> in-band signalling as C's standard strings Neat analogy ! > reference count ... copies ... only then is StringB copied You're right I should - and will - use this. But note it won't cover cases where the user modifies/copies the string from outside the API. The lib won't be aware. > your idea is conceptually brilliant! Oh I wish the neg offset header was my invention ! Alas it was at least used in Microsoft' BSTR and later by the famous antirez/sds (https://github.com/antirez/sds) > no nested macros I hear you. I thought it made them more readable. > is all that's going on I also (maybe naively) pretend to make mem faults occur less/at all.
In Show HN: Stricks – managed C strings library
Most of the code I write has a spec of input and output being some form of text. Still, I tend to write that in languages that have safe string handling and drop into C only when the profiler indicates that's useful. When handling strings in C, it's useful to use the string functions from glib or pull in one of the specifically safe string handling libraries and not use any C stdlib functions for strings at all. There are a number of C strings libraries safer to use than the standard library, and many of them are simpler, more feature-rich, or both. * https://github.com/intel/safestringlib (MIT licensed) * https://github.com/rurban/safeclib (MITish) * https://github.com/mpedrero/safeString (MIT licensed) * https://github.com/antirez/sds (BSD 2-clause, and gives you dynamic strings) * https://github.com/maxim2266/str (BSD 3-clause) * https
Read the rest
://github.com/xyproto/egcc (GPL 2.0, includes GC on strings) * https://github.com/composer927/stringstruct (GPL 3.0) * https://github.com/c-factory/strings (MIT licensed) * https://github.com/cavaliercoder/c-stringbuilder (MIT licensed, does dynamic) If one does use the C standard library directly for handling strings, the advisories from CERT, NASA, Github, and others should be welcome advice (CERT's advice, BTW, includes recommending a safer strings library right off).
In Git's list of banned C functions

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.