I think faulting on dereferencing 0 is a hardware function and yes, most hardware does so. Not so Z, where traditionally much of the "API" is chained off of the PSA.
Z faults on references to (in the assembler vernacular; de-referencing in the C vernacular) x'800' and immediately above, right? (Do I have that address right?) Z faults (usually, for an application) on writes to 0: *((char *)NULL) = 'A'; Charles -----Original Message----- From: IBM Mainframe Assembler List [mailto:[email protected]] On Behalf Of John Melcher Sent: Wednesday, September 9, 2020 1:49 PM To: [email protected] Subject: Re: Deep Cuts On most of the **IXs that I've used in the past dereferencing NULL as defined below will get you some kind of an exception (maybe addressing, maybe protection, maybe "malformed instruction"). (De)Referencing address zero isn't allowed. Failing to assign NULL to a pointer after you've done a FREE(), fails the code review. I presume (silly me) that NULL ends up being something similar to IEEE floating point "NaN". -----Original Message----- From: IBM Mainframe Assembler List <[email protected]> On Behalf Of Charles Mills Sent: Wednesday, September 9, 2020 3:17 PM To: [email protected] Subject: Re: Deep Cuts *** External email: Verify sender before opening attachments or links *** > If a null pointer constant is converted to a pointer type, the > resulting pointer, called a null pointer, is guaranteed to compare > unequal to a pointer to any object or function. Doesn't that say "0 is never a valid address"? Or at least "zero never compares equal to the address of any actual object"? "0 is never equal to any valid address"? Seems about the same to me. Although yes, you can de-reference 0. The following code has been working for years across multiple releases of z/OS and LE: psa* psaPtr = NULL; tcb* tcbPtr = (tcb *)psaPtr->psatold; tiot* tiotPtr = (tiot *)tcbPtr->tcbtio; I think most C's define NULL as simply zero. That is why the need for nullptr in the newer C++ standard. The following can be somewhat astonishing. Given int foo(int x); int foo(myclass *x); The statement bar = foo(NULL) matches against the second overload, not the first. Ah! I am looking at MS VS 2010 C. (I am offline from Z and not going to IPL just for this.) NULL is defined as /* Define NULL pointer value */ #ifndef NULL #ifdef __cplusplus #define NULL 0 #else #define NULL ((void *)0) #endif #endif So perhaps what I wrote about the overloads is not true. Or perhaps it is: http://TOC.ASG.COM:8080/?dmVyPTEuMDAxJiY2ZjRjZTdjZmQ1YzcwNGVmMz01RjU5Mzg1OF81NzE4Ml8xMTk3M18xJiY2MjBkYzhiNDNkZmJkOTk9MTIzMiYmdXJsPWh0dHBzJTNBJTJGJTJGc3RhY2tvdmVyZmxvdyUyRWNvbSUyRnF1ZXN0aW9ucyUyRjEyODIyOTUlMkZ3aGF0LWV4YWN0bHktaXMtbnVsbHB0ciUyRjE5MDE0NjQ0JTIzMTkwMTQ2NDQ= Charles -----Original Message----- From: IBM Mainframe Assembler List [mailto:[email protected]] On Behalf Of Bob Raicer Sent: Wednesday, September 9, 2020 9:14 AM To: [email protected] Subject: Re: Deep Cuts On Sun, 6 Sep 2020 16:48:18 -0700 Charles Mills wrote: > I'm familiar with the use of NULL as a "special" value. I think > the C > standard says that 0 may never be a valid address. The ISO/IEC 9899:20xx "C" standard cites no restriction on the value zero being an invalid address. An extraction from the standard: Topic 6.3.2.3 Pointers An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation. An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant. If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function. In other words, the standard requires that the simple assignment of the integer value zero to a pointer causes that pointer to be assigned the implementation defined value of NULL. For example: char *somepointer = 0; A conforming compiler treats the above assignment as: char *somepointer = NULL; While on most implementations this assigns the value zero to "somepointer", it is not necessarily so; the value of NULL may be any bit pattern which satisfies the constraints stated in the standard. Most implementations define NULL (for example, in stdlib.h or stddef.h) as: #define NULL ((void *)0) An example of an implementation dependent way to get the value zero assigned to a pointer is shown below. The "trick" here is that the value being assigned is not a constant expression. volatile int intzero = 0; char *somepointer = (char *)intzero; C does not prohibit dereferencing the NULL pointer; rather it makes it undefined (and implementation dependent) behavior. Certainly, on an IBM mainframe beginning with the S/360 and continuing to the present, it would be awkward (and obnoxious) to be unable to reference the PSA via a pointer variable.
