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…
C Strings and my slow descent to madness
251–260 of 329 posts
Re: C Strings and my slow descent to madness
#252Earlier 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.
Re: C Strings and my slow descent to madness
#253Earlier quoted context omitted.
> especially on the memory management side. Libc string functions don't manage memory. They can be used no matter where your strings are stored. It is more of a choice between generality vs convenience in common cases.
I think this is the main culprit of the libc string functions, you have to provide buffers to store results, and the responsibility of managing those individually can be annoying, and bug prone, resulting in vulnerabilities. Passing an allocator (like Zig) or a container (like in my framework) to anything that needs to allocate some memory to store a result is both explicit, low overhead and quite convenient in pract…
Re: C Strings and my slow descent to madness
#254Earlier quoted context omitted.
Which is why most applications ping back into POSIX when available, not that fixes the security issues with the standard library.
Which parts of posix? What can I #include in a posix environment to get better string handling in C? (Or maybe I’m misinterpreting your comment?)
First part of my comment relates to C library in general, second part of my comment refers to strings and arrays, even if not explicitly.
Re: C Strings and my slow descent to madness
#255Earlier quoted context omitted.
snprintf has very similar performance pitfalls.
no, because the size argument is only an upper bound on how many bytes can be written into the destination. snprintf (huge_buf, huge_buffer_size, "%d", 1); will write two bytes into huge_buf, regardless of huge_buffer_size (assuming it is 2 or larger).
Re: C Strings and my slow descent to madness
#256Re: C Strings and my slow descent to madness
#257Earlier quoted context omitted.
What’s the ownership story for string views?
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).
Re: C Strings and my slow descent to madness
#258"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…
You've grown to love the footguns and hundreds of thousands of security holes that null-terminated strings have introduced over the decades? It's not so much a question of different is bad, it's that having one of the six positions for your car's stick shift be marked 'Self-destruct' is... Sub-optimal. I'm sure you're smart enough to operate that car safely, but the ditches seem to be filled with burnt-out husks. Tab…
Re: C Strings and my slow descent to madness
#259Pop 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…
> The delightful answer is none of them. No. Sorry. This is bad programming. C'mon. I started programming back in the 8080, 8085, 6502, etc. days. I had to program some prototype computers using a hex keypad while entering raw machine code (not even assembler). I still own a couple of these: https://i.imgur.com/ZsIJj1p.png In a couple of cases I had to take this approach to bootstrap Forth on a 6502, then write a ful…
In C everyone starts out as a "bad programmer". In other languages people are merely inexperienced.
>however, someone with deep-rooted experience in these languages who jumps into C is very likely to do some truly horrific things. The language isn't the problem, at all.
You are contradicting yourself.
Re: C Strings and my slow descent to madness
#260K&R contains this beautiful koan-like string copy code: while (*t++ = *s++) ; Honestly the elegance of this thing was one of the hooks that made me fall in love with C. But this was from a now-forgotten age of innocence, as there are so many "nopes" around this line-and-a-half that one would, rightly, be tarred and feathered for ever putting it in a program today.
Could you explain why this line should be discouraged? I'm a beginner in C, so I really don't know. That's why I'm asking.