> I don't think there's much of a difference in practice between the two. If you admit "bad data" into your language, you very quickly spiral into true undefined behavior.
Well, by your definition, it would indeed be basically impossible to turn C into a well-defined language. You'd have to make absolutely radical changes to memory management, pointers, etc.
So then, can we at least agree that it would be a good idea to minimize undefined behavior in C? Sure, we can't fix bad pointer accesses, and I get why this stuff was there in the '70s. But modern CPUs have largely homogenized on some basic attributes. How about we decide that "two's complement has won" and thus clearly define what happens on signed integer overflow? How about we state that "a byte is 8-bits"? And so on ... all of the things that are true of basically every major CPU in use, and that would be exceedingly unlikely to ever change again in the future.
And this can still be offered as an optional flag. But when enabled, it's just a little bit of added protection against an oversight turning into a major security vulnerability, and at virtually no cost.
Out of curiosity, are there expensive runtime checks needed to handle signed integer overflow or do processors actually know about two's complement? If you had to check every single time you touched an int that could be bad. In general, what UB can be defined with static fixes, and what UB can only be defined with dynamic fixes?
It depends on the architecture. The VAX could be set (on a function-by-function basis) to either ignore 2's complement overflow, or automatically trap. The Intel x86 line can trap, but you have to add the INTO instruction, possibly after each math operation that could overflow. I don't think the Motorola 68k could trap on overflow. The MIPS has two sets of math operations, one that will automatically trap on 2's complement overflow, and a set that won't (and at the time, the C compiler I used only used the non-trap instructions).
That's why the C standard is so weasly with overflow---it varies widely per CPU.
Well, by your definition, it would indeed be basically impossible to turn C into a well-defined language. You'd have to make absolutely radical changes to memory management, pointers, etc.
So then, can we at least agree that it would be a good idea to minimize undefined behavior in C? Sure, we can't fix bad pointer accesses, and I get why this stuff was there in the '70s. But modern CPUs have largely homogenized on some basic attributes. How about we decide that "two's complement has won" and thus clearly define what happens on signed integer overflow? How about we state that "a byte is 8-bits"? And so on ... all of the things that are true of basically every major CPU in use, and that would be exceedingly unlikely to ever change again in the future.
And this can still be offered as an optional flag. But when enabled, it's just a little bit of added protection against an oversight turning into a major security vulnerability, and at virtually no cost.