Yes, that's hardware, but a nice place where hardware ain't C.
I'm just sayin'...
Yes, that's hardware, but a nice place where hardware ain't C.
I'm just sayin'...
And an optimizing compiler is free to transform its generated code based on the assumption that the code's behavior is defined.
An optimizing compiler is free to transform its generated code based on the assumption that undefined behaviour never occurs.
""" As we say, the volume is almost all on the surface. Even in 3 dimensions the unit sphere has 7/8-ths of its volume within 1/2 of the surface. In n-dimensions there is 1–(1/2^n) within 1/2 of the radius from the surface.
This has importance in design; it means almost surely the optimal design will be on the surface and will not be inside as you might think from taking the calculus and doing optimizations in that course. The calculus methods are usually inappropriate for finding the optimum in high dimensional spaces. This is not strange at all; generally speaking the best design is pushing one or more of the parameters to their extreme—obviously you are on the surface of the feasible region of design! """
The issue is design axis's are entangled. And also figures of merit are nonlinear. Twice as whatever doesn't mean twice as good.
1. you're not required to use C
2. an extension to the C standard can decide to define that behaviour
(void*)(intptr_t)0
can in principle be more involved than a noop.The latter is nothing unusual, x86 has it as well.
Maybe everyone who wrote real-mode systems software either ignored that bit of the C standard, or they fudged around it (IIRC the IVT is an array and the first entry doesn't matter, so you can start a few bytes past zero), or they used assembly to access it.
long zero = 0;
struct IVT * ivt_ptr = (struct IVT *)zero;
and struct IVT * ivt_ptr = 0;
/* or (struct IVT *)0 if you like that better stylistically */
The former gives you a pointer whose bits are all 0. The latter gives you a null pointer. On systems where 0 is a valid memory address the compiler should pick some other address that is not valid.Similarly, these two are not necessarily the same:
if ( ivt_ptr == 0 ) ...
and if ( ivt_ptr == (struct IVT *)zero ) ...
/* or if ((long)ivt_ptr == zero ) ... */
0 only represents the null pointer in C when it is the constant 0.See this for more information: http://c-faq.com/null/
Not necessarily. Null dereference is undefined behavior so it may as well access some valid memory.
Even on platforms where 0 is a valid address, practical compilers tend to use 0 as null constant because it simplifies implementation (easy to check for null, matches the C syntax without WTFs).
This comes at the cost of making some small part of memory unusable to portable C code (nobody will believe you when you return 0 from malloc if 0 happens to be considered null), but that's fine because such memory is typically used for machine-specific, nonportable stuff anyway.
And of course dereferencing 0 isn't impossible in practice on arches which support this. Compilers for such machines usually can be coerced to generate code which accesses 0, you just have to live with the fact that your code isn't considered "valid, portable C" anymore.
So if the board designer wired everything up to map RAM at address 0, then yes, you'd be able to dereference a pointer to address 0.
Completely beside the point, though. Dereferencing NULL is always undefined behaviour in C.
AVR Processors don't have bus faults. Some machines I've worked on have RAM based at address zero.
It's also perfectly fine on x86, in kernel memory page 0 is often mapped, the OS is the one mapping page 0 so that userland dereferencing it faults.
In fact, Linux had several privilege escalation bugs which involved putting something at 0 and executing a buggy syscall which loaded this thing due to NULL dereference and believed it's some legit internal kernel data.
* Well, this is implemented by the default system toolchain. You'r particular toolchain can opt out of this behavior if they want to.
Or it could document and provide a well defined behavior of derefrencing a NULL pointer.
(e.g. gcc provides -fdelete-null-pointer-checks to control this)
as(1).