Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
JerryWang
Advisor
Advisor
The sets of these three predicate expressions can easily confuse ABAP newbies, if the explanation for them in corresponding ABAP help document are not seriously taken.

The following text are copied from ABAP help:


IS BOUND


It checks whether a reference variable contains a valid reference. A data reference variable that contains a stack reference, on the other hand, can become invalid even if the reference data object is removed from the stack.

IS INITIAL


checks whether the operand operand is initial. The expression is true, if the operand contains its type-friendly initial value.

IS ASSIGNED


checks whether a memory area is assigned to a field symbol. The expression is true if the field symbol points to a memory area.


I saw in our internal system that our colleague horst.keller has written a report DEMO_IS_NOT_BOUND to demonstrate the difference between IS INITIAL and IS BOUND.

Here below is his original report consists of 22 lines.


REPORT demo_is_not_bound.

CLASS cls DEFINITION.
PUBLIC SECTION.
CLASS-DATA dref TYPE REF TO i.
CLASS-METHODS main.
ENDCLASS.

CLASS cls IMPLEMENTATION.
METHOD main.
DATA number TYPE i.
dref = REF #( number ).
ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
cls=>main( ).
IF cls=>dref IS NOT INITIAL AND
cls=>dref IS NOT BOUND.
cl_demo_output=>display(
'stack reference is not initial but not bound' ).
ENDIF.

I have made modifications on top it and added some more code to include IS ASSIGNED into discussion.

Here below is my report:


REPORT zcontext.
CLASS cls DEFINITION.
PUBLIC SECTION.
CLASS-DATA dref TYPE REF TO i.
CLASS-METHODS: main,check.
ENDCLASS.

CLASS cls IMPLEMENTATION.
METHOD main.
DATA number TYPE i.
dref = REF #( number ).
ENDMETHOD.

METHOD check.

WRITE: / 'dref IS BOUND? ', boolc( dref IS BOUND ).
WRITE: / 'dref IS INITIAL? ', boolc( dref IS INITIAL ).

FIELD-SYMBOLS: <any> TYPE i.

WRITE: / '<any> IS ASSIGNED? ', boolc( <any> IS ASSIGNED ).
IF <any> IS ASSIGNED.
WRITE: / '<any> IS NOT INITIAL? ', boolc( <any> IS NOT INITIAL ). "It will dump without above IS ASSIGNED check
ENDIF.


ASSIGN dref->* TO <any>.
WRITE: / '<any> IS ASSIGNED? ', boolc( <any> IS ASSIGNED ).
IF <any> IS ASSIGNED.
WRITE: / '<any> IS NOT INITIAL? ', boolc( <any> IS NOT INITIAL ). "It will dump without above IS ASSIGNED check
ENDIF.

DATA: a TYPE REF TO i.
DATA: b LIKE REF TO a.

FIELD-SYMBOLS: <any2> TYPE REF TO i.

b = REF #( dref ).
ASSIGN b->* TO <any2>.
WRITE: / '<any2> IS BOUND? ', boolc( <any2> IS BOUND ).
WRITE: / '<any2> IS INITIAL? ', boolc( <any2> IS INITIAL ).
WRITE: / '<any2> IS ASSIGNED? ', boolc( <any2> IS ASSIGNED ).

CLEAR: dref.
WRITE: / 'After clear'.
WRITE: / 'dref IS BOUND? ', boolc( dref IS BOUND ).
WRITE: / 'dref IS INITIAL? ', boolc( dref IS INITIAL ).
WRITE: / '<any2> IS BOUND? ', boolc( <any2> IS BOUND ).
WRITE: / '<any2> IS INITIAL? ', boolc( <any2> IS INITIAL ).
WRITE: / '<any2> IS ASSIGNED? ', boolc( <any2> IS ASSIGNED ).

ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
cls=>main( ).
cls=>check( ).

Not bound, but also not initial reference


Such kind of reference could be produced by declaring a reference pointing to a local variable defined in a method, that is, a stack reference.

In my example, the life time of local variable number is only valid within the method main, once main method is executed, the number variable is not valid any more, the same holds true for the reference dref pointing to it. As a result, when double clicking dref, it shows "FREED STACK:{A:1*\TYPE=I}".



According to SAP help, the reference variable dref now contains an INVALID reference so IS BOUND on it returns false. On the other hand, dref does not contain an initial value, but now just points to an invalid value, so IS INITIAL also returns false.

Dangling pointer and wild pointer




I still remember when I was studying C programming language in my university in year 2001, there are two concepts Dangling pointer and wild pointer.According to wikipedia, Dangling pointers and wild pointers in computer programming are pointers that do not point to a valid object of the appropriate type.
Although both can lead to serious memory violation trouble, they can still be differentiated. Dangling pointers arise during object destruction, when an object that has an incoming reference is deleted or deallocated, without modifying the value of the pointer, so that the pointer still points to the memory location of the deallocated memory.Now go back to the ABAP example, the variable dref, which IS NOT BOUND AND IS NOT INITIAL, is a dangling reference.

Wild pointers, on the other hand, are created by omitting necessary initialization prior to first use. Thus, strictly speaking, every pointer in programming languages which do not enforce initialization begins as a wild pointer.

Undefined behavior




At least in C Programming world, when we talk about Dangling pointer and wild pointer, we usually tend to link both to another concept "Undefined behavior".
In computer programming, undefined behavior (UB) is the result of executing computer code whose behavior is not prescribed by the language specification to which the code adheres, for the current state of the program (e.g. memory).

I still remember the struggling old days when I was using C to develop a P2P application in Linux: access to dangling pointer will not lead to any immediate runtime errors, instead, the program will terminate abnormally in a position which is far far away from the location where dangling pointer is used, which makes the root cause trouble shooting become a nightmare. Anyway in ABAP thanks to the safeguard of ABAP runtime, there is not undefined behavior as in C. Most of the time the program terminates with a meaningful exception and a short dump.

IS ASSIGNED


Things get a little bit more complex when taking field symbol into consideration.

When you declare a field symbol without any actual memory area assignment, and you try to evaluate it using IS NOT INITIAL, you will meet with runtime error.

Example: if you comment out the IF statement in line 27,



You will get runtime error GETWA_NOT_ASSIGNED.



This gives us a hint that every time when you try to access field symbol's value, even if you just would like to check whether it contains initial value or not, you must first use IS ASSIGNED which is the prerequisite of all subsequent value evaluation and initial check.

How about a NOT BOUND, NOT INITIAL AND IS ASSIGNED field symbol?


Yes you can construct a field symbol of such type following the similar idea.

In my sample report, field symbol <any2> fulfills the criteria.

In debugger double click it we can observe it has a memory area assigned, so both IS NOT INITIAL and IS ASSIGNED returns true.

And since it points to an invalid memory area, IS BOUND returns false.





Further reading









2 Comments