How to test a pointer?



IBM's cross-platform compiler PL/I for MVS, VM & VSE, OS/390 and Enterprise PL/I for z/OS

How to test a pointer?

Postby Pedro » Thu Nov 19, 2015 6:59 am

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?
Pedro Vera
User avatar
Pedro
 
Posts: 684
Joined: Thu Jul 31, 2008 9:59 pm
Location: Silicon Valley
Has thanked: 0 time
Been thanked: 53 times

Re: How to test a pointer?

Postby Pedro » Thu Nov 19, 2015 7:24 am

I tried binvalue:
If (myvar_ptr ¬= binvalue(Null()) ) Then

but get:
IBM1736I S  Comparison of POINTER to FIXED BIN is invalid. 
Pedro Vera
User avatar
Pedro
 
Posts: 684
Joined: Thu Jul 31, 2008 9:59 pm
Location: Silicon Valley
Has thanked: 0 time
Been thanked: 53 times

Re: How to test a pointer?

Postby Robert Sample » Thu Nov 19, 2015 9:24 am

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?
Robert Sample
Global moderator
 
Posts: 3719
Joined: Sat Dec 19, 2009 8:32 pm
Location: Dubuque, Iowa, USA
Has thanked: 1 time
Been thanked: 279 times

Re: How to test a pointer?

Postby prino » Thu Nov 19, 2015 5:18 pm

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.
Robert AH Prins
robert.ah.prins @ the.17+Gb.Google thingy
User avatar
prino
 
Posts: 635
Joined: Wed Mar 11, 2009 12:22 am
Location: Vilnius, Lithuania
Has thanked: 3 times
Been thanked: 28 times

Re: How to test a pointer?

Postby Pedro » Fri Nov 20, 2015 12:28 am

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.
Pedro Vera
User avatar
Pedro
 
Posts: 684
Joined: Thu Jul 31, 2008 9:59 pm
Location: Silicon Valley
Has thanked: 0 time
Been thanked: 53 times

Re: How to test a pointer?

Postby prino » Fri Nov 20, 2015 3:39 pm

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.
Robert AH Prins
robert.ah.prins @ the.17+Gb.Google thingy
User avatar
prino
 
Posts: 635
Joined: Wed Mar 11, 2009 12:22 am
Location: Vilnius, Lithuania
Has thanked: 3 times
Been thanked: 28 times

Re: How to test a pointer?

Postby steve-myers » Fri Nov 20, 2015 6:24 pm

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.
steve-myers
Global moderator
 
Posts: 2105
Joined: Thu Jun 03, 2010 6:21 pm
Has thanked: 4 times
Been thanked: 243 times


Return to PL/I

 


  • Related topics
    Replies
    Views
    Last post