| ▲ | oleganza 11 hours ago |
| Why is null-terminated C string considered a "billion dollar mistake", but UB isn't? |
|
| ▲ | DonaldPShimoda 11 hours ago | parent | next [-] |
| The "billion-dollar mistake" was about implicitly nullable values, i.e., allowing a variable with type `T` to also be set to `null`, not null-terminated strings. Anyway, one argument is that UB is fundamentally useful in languages that are insufficiently type-safe, like C and C++. The "holes" in the specification allow for regions where the compiler can optimize the code in ways you may not expect. As we have developed more advanced type systems, the utility of undefined behavior has lessened considerably. |
| |
| ▲ | returningfory2 10 hours ago | parent [-] | | Agreed that this is why a lot of people support the current UB situation, but the history of UB makes this feel wrong: > As far as I can tell, C89 did not use performance as a justification for any of its undefined behaviors. They were non-portabilities, like signed overflow and null pointer dereferences, or they were outright bugs, like use-after-free. But now experts like Chris Lattner and Hans Boehm point to optimization potential, not portability, as justification for undefined behaviors. I conclude that the rationales really have shifted from the mid-1980s to today: an idea that meant to capture non-portability has been preserved for performance, trumping concerns like correctness and debuggability. https://research.swtch.com/ub | | |
| ▲ | 4 hours ago | parent | next [-] | | [deleted] | |
| ▲ | DonaldPShimoda 8 hours ago | parent | prev [-] | | Oh undoubtedly; I didn't mean to imply that performance was the reason behind the origin of UB, though I can see how my comment would read that way. Thank you for adding the note! |
|
|
|
| ▲ | Guvante 11 hours ago | parent | prev | next [-] |
| Null terminated strings were an intentional compromise, known to be inferior for execution but superior for memory Null being an "allowed" value for pointers is the mistake e.g. what became nullptr. "Allowed" because garbage values are garbage. |
| |
| ▲ | account42 11 hours ago | parent [-] | | Think of the alternative where we'd be dealing with endless issues because someone though 255 or 2^16-1 characters ought to be enough for everyone. | | |
|
|
| ▲ | fooker 9 hours ago | parent | prev | next [-] |
| This comes from a fundamental misunderstanding of what UB is. Think of this piece of code - `y * x / y`. Would you like to simplify it to just `x` ? You need to either lean on UB to do so or have some magical way to prove that y can not be 0. Otherwise this transformation changes behavior, and is illegal. |
| |
| ▲ | colejohnson66 7 hours ago | parent [-] | | Why not just execute what I wrote? Maybe I'm doing some rounding? | | |
| ▲ | fooker 3 hours ago | parent | next [-] | | Because we want people to write simple idiomatic code that runs fast today and also in ten years on alien hardware. > Maybe I'm doing some rounding? Compilers won't do this optimization when it is illegal to. If you disagree with the compiler's idea of what is legal, you can either write inline assembly, or put this code into an always inlined, but never optimized function. | |
| ▲ | layer8 5 hours ago | parent | prev [-] | | Because we want compilers to perform the optimizations, not programmers. |
|
|
|
| ▲ | nicoburns 11 hours ago | parent | prev | next [-] |
| Probably because null-terminated strings are completely avoidable, whereas some amount of UB is all but required for performance (albeit C and C++ have far too much). |
|
| ▲ | ameliaquining 10 hours ago | parent | prev [-] |
| I recommend this explanation of why UB is good and necessary (but C and C++ are doing it wrong, defining some things as UB that really shouldn't be): https://www.ralfj.de/blog/2021/11/18/ub-good-idea.html |