Page 1 of 1

How to test a pointer?

PostPosted: Thu Nov 19, 2015 6:59 am
by Pedro
I am new to PLI and I beg your indulgence for a simple question.

I am modifying an existing program. It already has a local option to display the program parameters. The result for the parameter in question is:
PARMS.myvar_PTR='FF000000'bx;


Then I assign the parameter value to a local variable:
Dcl   myvar_ptr Ptr; 
myvar_ptr = parms.myvar_ptr;


The compiler does not like this:
If (myvar_ptr ¬= 'FF000000'x) Then

It complains about comparing a pointer to a character (or something like that)

In the same program, I found the use of NULL(), but when I use it:
If (myvar_ptr ¬= Null() ) Then
  Call mysub     

it seems to be true in the 'ff000000'x case. How am I supposed to test the pointer so as not to use it if it has not been set?

Re: How to test a pointer?

PostPosted: Thu Nov 19, 2015 7:24 am
by Pedro
I tried binvalue:
If (myvar_ptr ¬= binvalue(Null()) ) Then

but get:
IBM1736I S  Comparison of POINTER to FIXED BIN is invalid. 

Re: How to test a pointer?

PostPosted: Thu Nov 19, 2015 9:24 am
by Robert Sample
I'd do something along the lines of
DCL (NULL) BUILTIN;
.
.
.
IF ¬( myvar_ptr = NULL() ) THEN CALL MYSUB;
NULL is used to determine if a pointer has been set; is there a problem you're having with NULL?

Re: How to test a pointer?

PostPosted: Thu Nov 19, 2015 5:18 pm
by prino
PL/I nowadays has two types of NIL values for pointers, the old, that has been around since the inception of PL/I on 24-bit systems, and is generated by the NULL() builtin, having a value of 'FF000000'bx, and the preferred new one, generated by the SYSNULL() builtin, having the value '00000000'bx.

However, you cannot compare pointers directly against these values. As Robert Sample said, you can only compare pointers to NULL() (or SYSNULL()) to determine if they are set (and never mix use of NULL() and SYSNULL() in the same program!). You can also compare a pointer to another pointer, but only for (in)equality.

However, PL/I has based storage and the UNION attribute. Both allow you to overlay a pointer with a "FIXED BIN (31)" and then compare the FIXED BIN (31) to whatever other numerical value you want, which should of course only be 0 or 4278190080 (aka 'FF000000'bx).

DCL P PTR;
DCL F FIXED BIN (31) BASED(ADDR(P));

DCL 1 * UNION,
      2 P PTR,
      2 F FIXED BIN (31);

And PL/I wouldn't be PL/I if there weren't a third way of doing things, and that's using the UNSPEC() builtin. This builtin only works on elementary variables (not on arrays or structures), and it will return the contents as a bit-string, but it is implementation dependent, i.e. it will return different values on z/OS and Windoze (yes, PL/I is available for the latter). Using something like

if unspec(myptr) = unspec(my_fixed_bin_31) /* or unspec(my_fixed_dec_7_comma_4) or unspec(my_char_4) */ then ...

you can compare anything with everything, without the compiler generating any messages, which is of course not something you should be doing, as a good programmer wants to get as many warnings as possible to inform him or her of as many things that need to be looked at!

I don't know what level of Enterprise PL/I you're using, but I've got a set of '*process' statements that will result in W-type messages for more situations than the standard IBM supplied compiler options give you, shout and I'll post them here, for EPLI up to Version 4.3, the latest version I can use.

Re: How to test a pointer?

PostPosted: Fri Nov 20, 2015 12:28 am
by Pedro
NULL is used to determine if a pointer has been set; is there a problem you're having with NULL?

When I compare the pointer with NULL(), the IF statement proceeds as if the value was non-zero.

Re: How to test a pointer?

PostPosted: Fri Nov 20, 2015 3:39 pm
by prino
Pedro wrote:
NULL is used to determine if a pointer has been set; is there a problem you're having with NULL?

When I compare the pointer with NULL(), the IF statement proceeds as if the value was non-zero.

Add a
put skip list(unspec(myptr));
/* or */
put skip list(hex(myptr));

before the test, to see what myptr really contains.

Re: How to test a pointer?

PostPosted: Fri Nov 20, 2015 6:24 pm
by steve-myers
Like Pedro, I rarely do PL/I. Probably 20 years since I wrote a PL/I program. I got to thinking are there any library functions in PL/I that return a pointer? Obviously the function used to allocate storage, but are there any others? Could they return NULL, as is the case with some C functions? If so, how do they know to return a SYSNULL or an old style NULL?

When I saw the definition of an old style NULL I got to thinking AMODE 24. After a while I sort of decided the odds of an AMODE 31 pointer being confused with with an old style NULL were pretty remote.