Live data from Hacker News

C Strings and my slow descent to madness

deusinmachina.net

101–110 of 329 posts

Re: C Strings and my slow descent to madness

#101

Earlier quoted context omitted.

There are several libraries or projects where people have done exactly that. You often end up with some kind of structure, or variations of structures, for strings: struct string { size_t length; char data[]; }; struct string { size_t length; size_t alloc; char *data; }; Those are just examples. The tricky part is figuring out the different ownership use cases you want to solve. Because C gives you so much freedom an…

IMHO that does not solve the main problem, that is individual lifetime management. I've seen many libs using this style of strings, not convinced by the practicality.

What is "individual lifetime management"?

Re: C Strings and my slow descent to madness

#102
wchar_t is a massive landmine that should never be used since its size varies by platform. The locale of the compiler has to match the end user for L prefixed strings to work correctly. Likewise char16_t and char32_t are just swimming against the easy path at this point. You're much better off sticking to UTF-8 and using the C11 u8 prefix on literals so you can use the regular string API and never have to worry about locale settings.

Re: C Strings and my slow descent to madness

#103

If you are using C and do some non-trivial work with strings you should either use a good library to handle strings or build your own. It is not that difficult in practice. The old C std lib is, in my opinion, outdated, obsolete and a very bad fit for complex string handling, especially on the memory management side. In my own framework, the string management module is using a dedicated memory allocator and a "high l…

> the C std lib is the weakest part of the C language and it should only be used as a fallback. I've been musing for a while now: what would it look like if we were to discard the C library and design a new one, leaving the language itself intact?

The old MacOS (pre-X) did just that. Strings were all "Pascal strings", ie. with the first byte containing the length of the actual string.

Building blocks for memory were also very different from stdlib, notably the use of Handles, which were pointers of pointers, so that the OS could move a block of data around to defragment the heap behind your back without breaking the memory addressing.

Re: C Strings and my slow descent to madness

#104
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…

Yup, there is also Linux's strscpy which doesn't require reading memory from the source string beyond the specified "count" bytes and the return value is idiot proof.

Re: C Strings and my slow descent to madness

#105

Earlier quoted context omitted.

I think it could be very nice. C is not perfect, there are some parts of the syntax that I strongly dislike, like casting or function pointers declaration... But it is overall a good enough syntax, much simpler than C++.

Amending the syntax is fun but rapidly becomes a slippery slope; soon enough you find yourself designing a new successor language, as has been done many times before. Simply scrapping the mostly-unhelpful C stdlib and inventing new, modern abstractions for allocation, IO, text, threading, etc seems like a more tractable problem.

I fully agree.

Re: C Strings and my slow descent to madness

#106

Earlier quoted context omitted.

strlcpy is nice due to the guaranteed NUL termination. strlcpy is not so nice due to the strange (IMO) return value of the number of characters in the source string . Which could be the number of characters copied or much, much larger than the number of characters copied. snprintf does the same thing. So using strlcpy is safe (by C's low bar) but using the return value may be highly unsafe.

The thing that annoys me the most about strlcpy is that it is supposed to be safer, but what happens in the case where the source string is not properly NULL terminated? You might think that it will stop at the character limit you specified, but that's not what it does. It just blows on past the end of the buffer looking for a \0 until it either finds one or causes a segmentation violation. IMHO I would like it much…

Linux's strscpy addresses these issues.

Re: C Strings and my slow descent to madness

#107
I once got called in to fix an SS7 stack suffering from poor performance. Pretty well written, and not obvious at first sight why it was going slow. Most of it was low-level bit fiddling, and some small strncpy's() - generally about 8 chars or so.

Didn't take that long to profile (well, printf's as no profiling available) and figure out it was the strncpy's causing the problem, but why? Well, there was a handy 8 megabyte buffer used for working memory that the strings were being copied into that for modification.

From the strncpy() man page:-

>If the length of src is less than n, strncpy() pads the remainder of dest with null bytes.

Ah. So every little strncpy was essentially copying the string then zeroing out 7,999,992 bytes. And there were lots of little strncpy's...

Re: C Strings and my slow descent to madness

#108
post #67

In well-written C, you don't work with strings the way you do in other HLLs. For example, extracting and copying substrings is something unnecessary, unless you want to modify the parent string. Otherwise, a substring is represented by a pointer and a size_t length, and can easily be printed that way via the "%.*s" printf specifier: const char *s = "Hello World!"; const char *world = s + 6; size_t world_len = 5; prin…

* consumes an int, not a size_t: https://port70.net/~nsz/c/c11/n1570.html#7.21.6.1p5

I love how in every C code snippet on every comment on this thread, somebody got something wrong. I take it as a sign that it's probably best to avoid C as much as possible.

Re: C Strings and my slow descent to madness

#109

If you are using C and do some non-trivial work with strings you should either use a good library to handle strings or build your own. It is not that difficult in practice. The old C std lib is, in my opinion, outdated, obsolete and a very bad fit for complex string handling, especially on the memory management side. In my own framework, the string management module is using a dedicated memory allocator and a "high l…

> the C std lib is the weakest part of the C language and it should only be used as a fallback. I've been musing for a while now: what would it look like if we were to discard the C library and design a new one, leaving the language itself intact?

The creator of this library (antirez) is a regular here on hn.

I believe this is used by Redis.

https://github.com/antirez/sds

Re: C Strings and my slow descent to madness

#110

Earlier quoted context omitted.

There are several libraries or projects where people have done exactly that. You often end up with some kind of structure, or variations of structures, for strings: struct string { size_t length; char data[]; }; struct string { size_t length; size_t alloc; char *data; }; Those are just examples. The tricky part is figuring out the different ownership use cases you want to solve. Because C gives you so much freedom an…

IMHO that does not solve the main problem, that is individual lifetime management. I've seen many libs using this style of strings, not convinced by the practicality.

It sounds like you’re rephrasing part of my comment back to me, or maybe I’m misinterpreting what you’re saying.

If you’re not convinced of the practicality, it sounds like you are simply not convinced of the practicality of doing string processing in C at all, which is a fair view point. String processing in C is somewhat a minefield. Libraries like Git’s strbuf are very effective relative to other solutions in C, but lack safety relative to other languages.

Post reply on HN