2 ms·
I mean yes in this case the problem is you're doing a dereference out-of-bounds, which makes a program not strictly conforming. The problem tends to be is that
by jkrejcha 2y ago
I mean yes in this case the problem is you're doing a dereference out-of-bounds, which makes a program not strictly conforming.
The problem tends to be is that the real world is much more (essentially) complex and the domain of C is that which needs to be able to deal with that essential complexity, which includes things like type punning and int-to-ptr casts and the like which makes programs not strictly conforming. As it stands, a lot of these rules make it impossible to implement a lot of... C libraries... in ISO C, let alone things like operating system kernels and the like.
> And no UD
I assume this means undefined behavior? But in any case, undefined behavior is okay to have in a language, it's good for when there are no portable semantics for a particular operation or failure mode[1]. It's generally essential (although some undefined behaviors would definitely be better served being implementation defined or unspecified).
It is also okay for programmers to eschew this portability (so if they want to narrow their focus from "anything that can run strictly conforming C" to a superset that targets say a specific memory model or set of processors).
[1]: For example, at an extreme example, what happens if the CPU starts burning up? Obviously the standard can't describe such semantics for how a program should behave in the face of this.
- nine_k 2y agoI agree, type punning exists, this is why I mentioned `union`, invented to make some type punning easier. An explicit mechanism like that is essential. Doing it implicitly is, to my mind, too dangerous to be beneficial. Same with undefined behavior. I'm fine with implementation-dependent behavior (like what size is `int`, etc). But modern compilers see UD and feel free to do anything, even removing the code in question. Such things should not be silent, or even a warning. Instead it should be something like `unsafe` sections in Rust: "I know what I'm doing, the usual safety assumptions are irrelevant here, do what I literally say". Doing weird things is sometimes required e.g. to handle memory-mapped hardware registers, etc. But such areas should be clearly delineated, for they are usually few. They also tend to not be portable. A CPU burning up, hardware malfunctioning, etc is usually a situation where all bets are off. An unanticipated pointer aliasing in a trivial program running on perfectly working hardware is a different case.