Live data from Hacker News

C Strings and my slow descent to madness

deusinmachina.net

21–30 of 329 posts

Re: C Strings and my slow descent to madness

#21

Okay, I agree that by default , C strings are bad. But it doesn't have to stay that way. Someone else in the comments mentioned antirez's sds library for dynamic strings. This works, but you could also easily roll your own. All you need is an init function, and perhaps an assert or other check at the end of it that the string has a nul terminator. At that point, type checking will let you blindly pass those strings (…

There's also RapidString, though the original author seems to have disappeared off of the internet. Would be curious to see benchmarks against sds.

Re: C Strings and my slow descent to madness

#22
post #6

Yes this is something to get use to. The BSDs created strlcpy(3) and wcslcpy(3) https://man.openbsd.org/strlcpy.3 https://man.openbsd.org/wcslcpy.3 which to me will help with some of these issues. Too bad other Operating Systems do not have these. On Linux there is libbsd to get these, but I would like to see these to be added to the stdc. Instead the c23 standard is messing with realloc(3) which could break some old…

Ushering out strlcpy() https://lwn.net/Articles/905777/

Re: C Strings and my slow descent to madness

#23
post #6

Yes this is something to get use to. The BSDs created strlcpy(3) and wcslcpy(3) https://man.openbsd.org/strlcpy.3 https://man.openbsd.org/wcslcpy.3 which to me will help with some of these issues. Too bad other Operating Systems do not have these. On Linux there is libbsd to get these, but I would like to see these to be added to the stdc. Instead the c23 standard is messing with realloc(3) which could break some old…

These functions are in the current POSIX draft - though not published, it's quite unlikely to be removed (someone actually specifically filed an issue against POSIX to try and get it removed, basically on the basis of "it's not perfect so it should be removed", and the issue got rejected on the basis that there's no consensus for removal, and it seems unlikely this will change), and as a result, the functions are getting added to glibc: https://sourceware.org/pipermail/libc-alpha/2023-April/14696...

Re: C Strings and my slow descent to madness

#24

Okay, I agree that by default , C strings are bad. But it doesn't have to stay that way. Someone else in the comments mentioned antirez's sds library for dynamic strings. This works, but you could also easily roll your own. All you need is an init function, and perhaps an assert or other check at the end of it that the string has a nul terminator. At that point, type checking will let you blindly pass those strings (…

The best way to write C is to treat strings as memory locations with characters and nothing more. Every such memory location has an allocated size, either statically at compile-time (with literals and arrays), or dynamically with malloc and friends. Treat string operations as mere memory operations and don't imagine them to be something else. The str* functions from the standard library are just convenience helpers which are not adding "string" functionality whatsoever.

Re: C Strings and my slow descent to madness

#25
post #5

With the woes of string.h being known, why not just use an alternative like https://github.com/antirez/sds ? I’ve also been having a blast with C because writing C feels like being a god! But the biggest thing that I like about C is that the world is sort of written on it! Just yesterday I needed to parse a JSON… found a bunch of libraries that do that and just picked one that I liked the API.

I encourage people to use sds if that's the best option.

However, I don't think that's the best option if you can roll your own.

I personally think that there should be two different types of strings: static and dynamic ones. The static ones should not be able to be changed, but the dynamic ones can serve as a "string builder" type of sorts.

Second, I don't see sds's first advantage (in the README) to be an advantage. Sure, you may have to explicitly pass the buffer in to C functions, but that tells you that you're calling a function that takes a char array rather than your string. It makes it more explicit.

Second, if you use my method of splitting static strings from dynamic strings, then sds's second advantage doesn't apply because the pointer will never change.

But the disadvantages of sds still apply, and both disadvantages are big since they easily lead to bugs. Hence, I think sds is not the best option if you can make your own.

Oh, another advantage of the static/dynamic split: I can implement small string semantics. For small enough strings, I use a union to put the array into the same bytes as the pointer, so on 64-bit machines, I can have 8-byte strings (including nul) before needing an actual allocation.

Re: C Strings and my slow descent to madness

#26

Okay, I agree that by default , C strings are bad. But it doesn't have to stay that way. Someone else in the comments mentioned antirez's sds library for dynamic strings. This works, but you could also easily roll your own. All you need is an init function, and perhaps an assert or other check at the end of it that the string has a nul terminator. At that point, type checking will let you blindly pass those strings (…

> by default , C strings are bad. C strings aren't bad. They can't be, because they don't exist. C doesn't have strings. And that is the issue. As you say, things get a lot better when you actually introduce strings as a concrete concept rather than a set of lose conventions.

There is no "loose convention". A C string is a null terminated string of non-null bytes. That's the definition. Working with them in memory-unconstrained environments is unnecessarily hard.

Re: C Strings and my slow descent to madness

#27
I don't use null terminated strings. ptr+len struct everywhere. And when I need to call an API, like fopen, I make a temporary copy of that string + the null termination, do my work and then free it.

You can printf non-null terminated strings too. Check printf("%.*s", length, strptr).

Re: C Strings and my slow descent to madness

#28
post #9

I stopped when I read strcmp returns 0 if two strings are equal and 1 if they aren't.

It's actually 0 if equal, positive if greater, negative if less than.

  > The strcmp() and strncmp() functions return an integer greater than, equal to, or less than 0, according to whether the string s1 is greater than, equal to, or less than the string s2.  The comparison is done using unsigned characters, so that ‘\200’ is greater than ‘\0’.

Re: C Strings and my slow descent to madness

#29
post #5

With the woes of string.h being known, why not just use an alternative like https://github.com/antirez/sds ? I’ve also been having a blast with C because writing C feels like being a god! But the biggest thing that I like about C is that the world is sort of written on it! Just yesterday I needed to parse a JSON… found a bunch of libraries that do that and just picked one that I liked the API.

> With the woes of string.h being known, why not just use an alternative like https://github.com/antirez/sds ?

That library really doesn't address any of the Unicode issues.

Re: C Strings and my slow descent to madness

#30
post #5

With the woes of string.h being known, why not just use an alternative like https://github.com/antirez/sds ? I’ve also been having a blast with C because writing C feels like being a god! But the biggest thing that I like about C is that the world is sort of written on it! Just yesterday I needed to parse a JSON… found a bunch of libraries that do that and just picked one that I liked the API.

Was going to say the same thing.

If you want Unicode in C a wrapper library is pretty much a given.

When I was adding Unicode support to the small scheme interpreter I like playing with I found a super simple string library, a bunch of generated code (who doesn’t love 1000 line switch statements) for dealing with utf-8 code points and bob’s your uncle. Could have probably found a library that did it all but the goal was learning and yak shaving.

Haven’t ever messed with the wide strings, seems like more of a hassle than they’re worth.

Post reply on HN