A pointer may be displaced by a numeric offset, and two pointers may be subtracted to obtain the offset between them. Both forms work in free-format expressions and in fixed-format C-spec expressions.
DCL-DS Buf QUALIFIED;
All CHAR(10);
END-DS;
DCL-S p1 POINTER;
DCL-S p2 POINTER;
DCL-S ch CHAR(1) BASED(p2);
DCL-S diff INT(10);
Buf.All = 'abcdefghij';
p1 = %ADDR(Buf.All);
p2 = p1 + 8; // ch is now 'i'
p2 = p2 - 1; // ch is now 'h'
diff = p2 - p1; // 7
ptr + n/ptr - nyield a pointer displacednbytes, addressing the same storage. The compound forms+=and-=do the same. A displaced pointer still aliases the original bytes, so writes through aBASEDvariable over it are visible in the storage it came from.ptr - ptryields the signed byte offset between the two pointers as a number. Reversing the operands negates the result, and a pointer minus itself is 0.<,>,<=,>=order two pointers by the byte each addresses.=and<>compare pointers for identity, which is also howptr = *NULLtests whether a pointer is set.
Two rules are worth stating explicitly:
- Subtracting two pointers requires both to address the same storage. Two pointers into separate allocations have no meaningful distance, and rather than return a number that would be wrong, the operation fails at runtime with RPG status
00222("pointer or parameter error"), trappable byMONITORor an(E)extender. - Displacing a pointer is not bounds-checked. Moving a pointer before or after the storage it addresses raises nothing at the point of the move; it is the program's responsibility to stay within the item. An access through a pointer that has left its storage fails when it is dereferenced.
Adding two pointers together is meaningless and is rejected at compile time.