>>22
Then most archs disregard that rule:
- A pointer is almost always represented using an integer value (or similar), sized the same as the size of the machine's registers.
- Usually, any address(which is the size of an integer) can be valid under certain circumstances on most archs.
- NULL is commonly equal to 0, and 0 may or may not be reserved by the OS for safety purposes, but even in those cases that it's reserved, it's usually possible to emulate that something exists at that address (same is true for any address).
Given those things, that means that as long as a pointer is stored as an unsigned int on a specific arch, that rule can be broken in practice. Reserving an address can make things slightly safer. Even if 0 wasn't reserved, you could for example reserve/alloc a small block of memory at a certain address, call that NULL, and set the access flags to that page to prohibit all access(read/write/execute/...), which would give the same results. Of course, someone could subvert or change that behaviour making whatever the address of NULL is a valid address, thus as long as a pointer is represented internally as an unsigned int, then it will be possible to break that ISO C rule(if it exists).
The real solution is to use another bit besides the pointer to mark validity. Be it a tag bit, or a more strange arch with tag bits, or something of that sort. Of course, since C is a low-level language which is usually used for efficiency reasons, something like that won't happen unless the CPU supports it natively.
There are always some minor differences and disregarded restrictions between a language definition and a language implementation, that's especially the case for low-level languages like C which are pretty close to the metal. When it comes to more high-level languages, the standards tend to be followed much more to the letter (except when there are errors in the standard...).