Live data from Hacker News

C Strings and my slow descent to madness

deusinmachina.net

271–280 of 329 posts

Re: C Strings and my slow descent to madness

#271

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…

> snprintf(buf, 80, argv[1]);

yeaaa, this has much bigger problems than a null write...

Re: C Strings and my slow descent to madness

#272
post #196

"We're not in Kansas any more, Toto" Or to paraphrase that "We're not in Python any more, and C is not Python". You know what sends me insane? Indentation and lack of fixed types in Python. But I don't have problems with C strings. Because I have grown to love and know C's string foibles just like the author will certainly not be driven insane by 'Python's shortcomings according to me'. The world is full of people wh…

Indentation and lack of fixed types aren't responsible for over 50% of known security issues in software. C's issue are not just harmless foibles. They cause real harm to the poor people actually using the software.

> Indentation and lack of fixed types aren't responsible for over 50% of known security issues in software.

there is no way of fixing this with a "string type". The errors come from IPC/Internet, and there will always be just a sequence of bytes, and some length, maybe, given by the user. Somewhere some code will have to trust this length, or compute a length.

Re: C Strings and my slow descent to madness

#273

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…

So then what do you do?

Re: C Strings and my slow descent to madness

#274
post #261

Earlier quoted context omitted.

I plan to bring such a proposal forward for the next version. Note that C already has everything to do this without much overhead, e.g. in C23 you can write: int N = 10; char buf[N] = { }; auto x = &buf; and 'x' has a slice type that automatically remebers the size. This works today with GCC / clang (with extensions or C2X language mode: https://godbolt.org/z/cMbM57r46 ). We simply can not name it without referring t…

You know what i think about auto :-) How is this not a quality of implementation issue? Any implementation is free to track all sizes as much as they want with the current standard. Either a implementation is forced to issue an error at run time if there is an out of bounds read/write and in that case its a very different language than C, or its feature as-if lets any implementation ignore.

Tracking sizes for purposes of bounds checking is QoI and I think this is perfectly fine. But here we can also recover the size with sizeof, so it is also required for compliance:

https://godbolt.org/z/qh7P93Tcd

And I agree that this is a misuse of auto. I only used it here to show that the type we miss already exists inside the C compiler, we simply can name it only by constructing it again:

char (buf)[N] = ...

but we could simply allow

char (buf)[:] =

and be done (as suggested by Dennis Richtie: https://www.bell-labs.com/usr/dmr/www/vararray.pdf)

Re: C Strings and my slow descent to madness

#275
post #267

Earlier quoted context omitted.

If you think about arrays as pointers, you will get a lot of things wrong, e.g. float m[10][10]; it not a an array of pointers, but a 2D dimensional array with 2D memory layout.

You are right, sizeof is the other big difference. I think these differences are small enough that it was a mistake separate the two. The similarities / differences do make them confusing.

How would you express a 2D memory layout with only pointers?

Re: C Strings and my slow descent to madness

#276

Earlier quoted context omitted.

You're probably right about consoles, and I was surprised to be wrong, but I checked, just to be sure. GCC and Clang are very nice compilers, but they are a different thing than the std lib. glibc, musl, the Windows C Runtime, iOS, Android, all have different implementations, sometimes outdated.

Gcc and clang are relevant here because memcpy is a builtin. It will not call libc for this. Same is true of MSVC. It's been that way on most modern compilers for about 20 years. That's why I'm saying rolling your own may be futile. Compilers , not just libc, have paid a lot of attention to getting those things fast.

What is true for memcpy (especially on small buffers) is not systematically true for string functions.

But testing is always there to the rescue, and these days we have Godbolt.

Re: C Strings and my slow descent to madness

#277

Earlier quoted context omitted.

Any data to back up that FUD?

Of course I have data, do you think I am pulling benchmarks out of a hat? But I have not published those benchmarks, if this is what you're asking, the Nintendo thing I am afraid I cannot reproduce easily as I no longer have this devkit on hand. About the strlen benchmark, this is something I've done a few years ago, that could be easy to run again, but I am not sure this is worth the effort just to convince a random…

> do you think I am pulling benchmarks out of a hat?

Yes. Share the data or you're spreading FUD.

Re: C Strings and my slow descent to madness

#278

This is from a C fan: If you are going to do any string heavy work, please use anything else than C (Python is pretty nice for this sort of stuff for instance). And if you need to use C anyway, then please use anything else than the string functions from the standard library. The C stdlib is (mostly) a leftover from the K&R era when opinions about what makes a good API were very different from today, and C was a much…

As a newcomer to C, why is it that the C standard library doesn't get updated? Newer languages seem to place a lot of emphasis on getting their standard libraries as useful as possible. It's odd to be told not to use the standard library functions but to write my own instead. I'm really doubting I can just sit down and hammer out string functions superior to string.h.

Re: C Strings and my slow descent to madness

#279
post #197
post #35

Earlier quoted context omitted.

It’s the access and control that it gives me! As when I’d pick Go because I was doing some concurrency, I can now explore a bunch of concurrency libraries, including some implementations that look a lot like Go channels. Want to watch a file for changes? I can do that all the way from taking to the kernel to picking a multi-platform library. I guess, I haven’t really found anything that I can’t do in C, and if I’m la…

I came from HLL like C# and I've come to love C for the same reasons. The only language I can fit in my head in its entirety and no one telling me this is the "right way" to write code, don't use this or that feature, etc. When I'm writing C, I am free. I absolutely love this freedom!

Exactly!

Re: C Strings and my slow descent to madness

#280

Earlier quoted context omitted.

You can use automatic memory management and not worry about it. Or you can use D's prototype ownership/borrowing system. Or you can encapsulate them in something that manages the memory. Or you can do ownership/borrowing by convention (it's not hard to do).

Automatic memory management makes copies?

No. Another word for automatic memory management is garbage collection.
Post reply on HN