Live data from Hacker News

C Strings and my slow descent to madness

deusinmachina.net

211–220 of 329 posts

Re: C Strings and my slow descent to madness

#211

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…

"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." unsigned int str_len(const char *s) { register const char *t; t = s; for (;;) { if (!*t) return t - s; ++t; if (!*t) return t - s; ++t; if (!*t) return t - s; ++t; if (!*t) return t - s; ++t; } } I still use this instead of stdlib strlen. Of course I also use software everyday that…

There are HN readers besides myself, not to mention hundreds if not thousands of others, who use various programs that use this function, such as

https://cr.yp.to/ucspi-tcp/install.html

https://cr.yp.to/daemontools/install.html

https://cr.yp.to/djbdns/install.html

https://cr.yp.to/clockspeed.html

https://cr.yp.to/software/qmail-1.03.tar.gz

https://smarden.org/runit/install.html

Re: C Strings and my slow descent to madness

#212
post #33

> Our last function is strcmp. It looks at two strings and determines whether they are equal to each other or not. If they are it returns 0. If they aren’t it returns 1. No it doesn’t. RETURN VALUES The strcmp() and strncmp() functions return an integer greater than, equal to, or less than 0, according as the string s1 is greater than, equal to, or less than the string s2. The comparison is done using unsigned charac…

I don't have MacOs to prove it but I believe `strcmp` on MacOs returns either 0, 1 or -1

It currently returns a character difference. Don’t rely on it, though!

Re: C Strings and my slow descent to madness

#213

Pop quiz, which of these is safe, given "char buf[80]" and arbitrary user input in argv[1]? gets(buf); scanf("%s", buf); strcpy(buf, argv[1]); scanf("%80s", buf); strncpy(buf, argv[1], 80); snprintf(buf, 80, argv[1]); ---- The delightful answer is none of them . The first three have no bounds checking at all, meaning that they will happily overflow the buffer to an arbitrary extent (gets, at least, will usually trigg…

Are you sure that strncpy does an out-of-bound write here? I believe it doesnt, but would give you an unterminated string in buf which is also... less than ideal (if the input is 80 non-null characters or longer).

Ugh, I had that in my comment before I "refactored" it. Fixed now, thanks for pointing it out.

Re: C Strings and my slow descent to madness

#214

Earlier quoted context omitted.

Pascal strings are also kind of bad though. All sub-string operations need allocation, or have to be defined with intermediate results which aren't "really" strings, so in that sense it's not an improvement on Zero-terminated strings. Equality tests are cheaper which is nice, since strings of different lengths compare unequal immediately, but most things aren't really improved. C++ string_view is closer to the Right…

D's strings were defined to be UTF-8 back in 2000. wstring is UTF-16, and dstring is UTF-32. Back then it wasn't clear which encoding method would turn out to be dominant, so we did all three. (Java was built on UTF-16.) As it eventually became clear, UTF-8 is da winnah, and the other formats are sideshows. Windows, which uses UTF-16, is handled by converting UTF-8 to -16 just before calling a Windows function, and c…

What’s the ownership story for string views?

Re: C Strings and my slow descent to madness

#215
post #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 mega…

The appearance of strncpy() in any source code is an immediate panic attack for me. It should never be used, and if it is used, it should be removed. Similar rule for sprintf(), all instances of which should be replaced by snprintf().

snprintf has very similar performance pitfalls.

Re: C Strings and my slow descent to madness

#216

Earlier quoted context omitted.

The appearance of strncpy() in any source code is an immediate panic attack for me. It should never be used, and if it is used, it should be removed. Similar rule for sprintf(), all instances of which should be replaced by snprintf().

Unfortunately there often isn't a better replacement in your standard library (embedded systems are weird). I ended up using strncpy followed by automatically setting the last byte of the string to null.

Wrap memccpy.

Re: C Strings and my slow descent to madness

#217

Earlier quoted context omitted.

Nintendo DS has probably had a lot less scrutiny than a major libc or recent GCC or clang [though you can probably target its ARM processor with that]. Also, for an older embedded platform they may choose to do optimization for code size rather than cycles or clock time. I'm going to have to doubt the start of your comment. Having seen a lot of libc implementations I think you are better off not wasting time optimizi…

On the contrary, I expected the Nintendo DS SDK to be well optimized, performance of memcpy can be critical on such a constrained hardware. And it was optimized, just not with the best tricks. I got the prefetching trick from Intel source code, except that I replaced the PLD instruction by a simple dummy load. And about strlen, you'd be surprised, some implems are very good, and some are not, depends on the compiler…

Any data to back up that FUD?

Re: C Strings and my slow descent to madness

#219

`strlcpy` is the function you probably want. but again it is not standard. https://lwn.net/Articles/507319/ I think the reason people don't want to standardise this kind of function is it often gives wrong behaviour. for example if you are trying to copy a string into a fixed buffer and its too long then often it is an error or potentially even a security bug to truncate it. so these functions generally do the 'wrong…

No, it’s not. The return value it provides is generally unwanted.

Re: C Strings and my slow descent to madness

#220

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…

> what happens in the case where the source string is not properly NULL terminated

That’s not a string.

Post reply on HN