3 ms·
> I recommend you re-read what I wrote in my post to see the whole point of undefined behavior and its critical importance. It is high time that this misconcept
by rstuart4133 2y ago
> I recommend you re-read what I wrote in my post to see the whole point of undefined behavior and its critical importance. It is high time that this misconception is put to rest.
Uhmmm, did you read what I said? I ask because it looks like a red haze descend after descended after you read the first few words. I've been writing C for 40 years. I know why C made integer overflows UB. It seemed perfectly sensible to me. That's why I didn't mention it. I'm not sure why you brought it up. In the article it says this:
Third, there are no integer overflow games going on here, as long as the code is compiled for a platform where an int is at least 32 bits. This is easy to see by inspecting the program. The termination problems are totally unrelated to integer overflow.
The thing I was discussing was C++ defining a infinite loop as UB. I'm not alone in thinking that was a bad idea. In the C standardisation group apparently also thinks that, because they are UB in C. You can check that for yourself: compile the Fermat program with gnu C and it behaves sanely. Compile it with gnu C++ is it gets the wrong answer. clang behaves identically. The author of the article also thinks it's amazing:
In other words, from the point of view of the language semantics, a loop of this form is no better than an out-of-bounds array access or use-after-free of a heap cell. This somewhat amazing fact ...
So yes, I'm firmly in the camp the C++ committee lost the plot here.
I think the way C and C++ handles UB belongs to a bygone era. In their defence when I was writing C 40 years ago there was no choice. Checking if every integer operation overflowed imposed an unacceptable performance penality. While today in languages like Rust compilers statically check for UB at compile time, back then C compilers were barely more than overblown assemblers. UB simply meant "you get what the hardware gives you". Notice that means on a given arch there was no real undefined behaviour. I knew perfectly well what would happen on x86 if an integer overflowed, I know whether a char was signed and I wrote my programs accordingly, sometimes deliberately exploiting what I knew would happen. UB only bit you hard when you ported your program.
What happened is compiler writers seeking to squeeze every last bit of performance pushed "undefined" to mean "since it's undefined, I can do whatever I damned well please", and with C++ and infinite loops they've managed to push that beyond absurdity. Meanwhile other languages have gone in opposite direction. Rather than giving programmers more rope to hang themselves with they've got runtime and compile time checks that either outright band undefined behaviour, or warn you about it.