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.

Reply via email to