News for hackers. Stuff that matters.
Re:Show HN: Stricks – managed C strings library by kazinator on Thursday March 25, 2021 @02:23PM (#26583610)
Here is mine, from 1999. The null-terminated data starts after the header.

  typedef struct {
    size_t len;
    long refcount;
  } dstr_t;

  dstr_t *dstr_alloc(const char *);
  dstr_t *dstr_duplicate(const dstr_t *);
  dstr_t *dstr_addref(dstr_t *);
  void dstr_release(dstr_t *);
  void dstr_dt(void *);
  dstr_t *dstr_concat(const dstr_t *, const dstr_t *);
  int dstr_cmp(const dstr_t *, const dstr_t *);
  int dstr_cmp_void(const void *, const void *);
  size_t dstr_len(const dstr_t *);
  const char *dstr_peek(const dstr_t *);
  char *dstr_take(const dstr_t *);
  dstr_t *dstr_extract(const dstr_t *, size_t, size_t);
  size_t dstr_chr(const dstr_t *, char);
  size_t dstr_rchr(const dstr_t *, char);

  #define dstr_len(D) ((D)->len)
  #define dstr_auto_clean(D) except_cleanup_push(dstr_dt, (D))
  #define dstr_clean() except_checked_cleanup_pop(dstr_dt,   except_call)
In the implementation, this is used for getting at the string data:

  #define dstr_str(D) ((char *)((dstr_t *) (D) + 1))
For some reason I didn't bother with the flexible array member trick.
Re:Show HN: Stricks – managed C strings library by alcover on Thursday March 25, 2021 @03:07PM (#26584113)
Why wouldn't you store capacity ? In your API the user has to put in a var and pass it around, like in bare C.
Re:Show HN: Stricks – managed C strings library by kazinator on Thursday March 25, 2021 @06:55PM (#26586679)
Capacity is required only if you plan to grow a string in place (so you know how much you can add before reallocating).

Reallocating is possible here because the string is one object, including the header. Reallocating would change the identity of the object, which is a non-starter when multiple places in the program are sharing the pointer via reference counting.

Therefore, all the strings are immutable here, and so all operations return a new string object.