Very interesting indeed.
If I understand this right, NULL is always zero (at the C level), but
"under the covers" the compiler
may assign other values to invalid pointers, if necessary. When reading
invalid addresses from pointer variables,
the compiler has to translate them to NULL (= zero) again, so that all
the C coding like "if (! ptr) ..." will work.
/* I don't like such coding, BTW; if I see such coding, I replace it
with "if (ptr != NULL)" */
This said, the C compiler on the mainframe COULD have chosen to
implement NULL addresses as,
for example, 0xFFFFFFFF. This is, BTW, what my Stanford Pascal compiler
uses for NIL pointers (minus one).
/* there is no such rule in Pascal that NIL must be equivalent to zero */
https://github.com/StanfordPascal
But in this case, that is, when implementing invalid addresses in C
(external NULL or zero)
as 0xFFFFFFFF, accessing the PSA using pointers containing zero could be
tricky;
if you assign NULL or zero to a pointer, C will translate it to 0xFFFFFFFF.
Maybe, if you overlay the pointer with an int, assigning zero could work,
because zero addresses in pointer variables are not translated and
dereferencing such pointer variables could still work?
Simply using a NULL pointer to access the PSA wouldn't work.
Kind regards
Bernd
Am 12.09.2020 um 01:19 schrieb Bob Raicer:
...
So, if some implementation defined this value as perhaps
0x7FFFFFFF, then the assignment:
char *somepointer = 0;
would set somepointer to 0x7FFFFFFF (assuming a pointer to char is
4-bytes in length).
Similarly, a statement like this:
if (0 == somepointer) ...
would cause a comparison to the value 0x7FFFFFFF, not zero.
The special treatment of the constant expression of zero in these
contexts is quirky and a source of great confusion. This
comp.lang.c FAQ aims to clarify the confusion:
URL: http://c-faq.com/null/machnon0.html
comp.lang.c FAQ list · Question 5.5
Q: How should NULL be defined on a machine which uses a nonzero
bit pattern as the internal representation of a null pointer?
A: The same as on any other machine: as 0 (or some version of
0; see question 5.4).
Whenever a programmer requests a null pointer, either by writing
"0" or "NULL", it is the compiler's responsibility to
generate whatever bit pattern the machine uses for that null
pointer. (Again, the compiler can tell that an unadorned 0
requests a null pointer when the 0 is in a pointer context; see
question 5.2.) Therefore, #defining NULL as 0 on a machine for
which internal null pointers are nonzero is as valid as on any
other: the compiler must always be able to generate the
machine's correct null pointers in response to unadorned 0's seen
in pointer contexts. A constant 0 is a null pointer constant;
NULL is just a convenient name for it (see also question 5.13).
(Section 4.1.5 of the C Standard states that NULL "expands to an
implementation-defined null pointer constant," which means that
the implementation gets to choose which form of 0 to use and
whether to use a void * cast; see questions 5.6 and 5.7.
"Implementation-defined" here does not mean that NULL might be
#defined to match some implementation-specific nonzero internal
null pointer value.)