Skip to Content

LOOP/READ field symbol of type generic table assigning field symbol behavior

Hello,


I've notice a behavior from ABAP that took me by surprise and I couldn't find anything about it.


When I try to access a table row of a internal table assigned to a field symbol of type generic type standard table through LOOP or READ assigning a inline declaration field symbol, even if the table is empty, an (unkown) memory area is assigned to field symbol.


SY-SUBRC is correctly set to 4 but the field symbol gets assigned.

I wrote a demo program to illustrate this.

REPORT zffs_test.

TYPES: BEGIN OF ty_table,
         amount TYPE i,
       END OF ty_table.

DATA gt_table TYPE STANDARD TABLE OF ty_table.

DATA subrc TYPE c LENGTH 1.

FIELD-SYMBOLS: <fs_any_table>            TYPE STANDARD TABLE,
               <fs_previously_declared>  TYPE any,
               <fs_previously_declared2> TYPE any.

START-OF-SELECTION.

* Assign GT_TABLE to field symbol of generic table type
  ASSIGN gt_table TO <fs_any_table>.

* Example1. 1- Loop ITAB. 2- INLINE declared field symbol.
* Result: SY-SUBRC = 4. Field sybol is not assigned. OK.
  LOOP AT gt_table ASSIGNING FIELD-SYMBOL(<fs_table>).
  ENDLOOP.

  subrc = sy-subrc.

  WRITE: 'Example1 - Loop 1'.
  WRITE: / 'SY-SUBRC = ', subrc NO-GAP, '.' .

  IF <fs_table> IS ASSIGNED.

    WRITE: 'Never written, as expected'.
  ELSE.

    WRITE: 'Not assigned, as expected.'.
  ENDIF.

* Example2. 1- Loop AT <FS_ANY_TABLE>. 2- Previously declared field symbol.
* Result: SY-SUBRC = 4. Field sybol is not assigned. OK.
  LOOP AT <fs_any_table> ASSIGNING <fs_previously_declared>.
  ENDLOOP.

  subrc = sy-subrc.

  SKIP.
  WRITE: / 'Example2 - Loop 2'.
  WRITE: / 'SY-SUBRC = ', subrc NO-GAP, '.' .

  IF <fs_previously_declared> IS ASSIGNED.

    WRITE: 'Never written, as expected'.
  ELSE.

    WRITE: 'Not assigned, as expected.'.
  ENDIF.

* Example3. 1- Loop AT <FS_ANY_TABLE>. 2- INLINE declared field symbol.
* Result: SY-SUBRC = 4. Field sybol is assigned. NOK.
  LOOP AT <fs_any_table> ASSIGNING FIELD-SYMBOL(<fs_table2>).
  ENDLOOP.

  subrc = sy-subrc.

  SKIP.
  WRITE: / 'Example3 - Loop 3'.
  WRITE: / 'SY-SUBRC = ', subrc NO-GAP, '.' .

  IF <fs_table2> IS ASSIGNED.

    WRITE:  'Assigned!'.
  ENDIF.

* Example4. 1- READ TABLE ITAB. 2- INLINE declared field symbol.
* Result: SY-SUBRC = 4. Field sybol is not assigned. OK.
  READ TABLE gt_table ASSIGNING FIELD-SYMBOL(<fs_table3>) INDEX 1.

  subrc = sy-subrc.

  SKIP.
  WRITE: / 'Example4 - Read 1'.
  WRITE: / 'SY-SUBRC = ', subrc NO-GAP, '.' .

  IF <fs_table3> IS ASSIGNED.

    WRITE: 'Never written, as expected'.

  ELSE.

    WRITE: 'Not assigned, as expected.'.
  ENDIF.

* Example5. 1- Loop AT <FS_ANY_TABLE>. 2- Previously declared field symbol.
* Result: SY-SUBRC = 4. Field sybol is not assigned. OK.
  READ TABLE <fs_any_table> ASSIGNING <fs_previously_declared2> INDEX 1.

  subrc = sy-subrc.

  SKIP.
  WRITE: / 'Example5 - Read 2'.
  WRITE: / 'SY-SUBRC = ', subrc NO-GAP, '.' .

  IF <fs_previously_declared2> IS ASSIGNED.

    WRITE: 'Never written, as expected'.

  ELSE.

    WRITE: 'Not assigned, as expected.'.
  ENDIF.

* Example6. 1- Loop AT <FS_ANY_TABLE>. 2- Previously declared field symbol.
* Result: SY-SUBRC = 4. Field sybol is not assigned. OK.
  READ TABLE <fs_any_table> ASSIGNING FIELD-SYMBOL(<fs_table4>) INDEX 1.

  subrc = sy-subrc.

  SKIP.
  WRITE: / 'Example6 - Read 3'.
  WRITE: / 'SY-SUBRC = ', subrc NO-GAP, '.' .

  IF <fs_table4> IS ASSIGNED.

    WRITE: 'Assigned!'.
  ENDIF.

Ouput:

In the debugger you can see that when assigning <fs_any_table> to an inline declared field symbol, the field symbol is automatically assigned on the first statement.

The documentation says:

“If the assignment is successful, sy-subrc is set to 0; if not, it is set to 4.”

True, that what happens. Although:

“If the assignment is not successful, the field symbol keeps its previous state. It is therefore not enough just to evaluate the predicate expression <fs> IS ASSIGNED in a dynamic ASSIGN; sy-subrc needs to be checked as well.”

The previous state of a field symbol declared previously is in fact unassigned, but the previous state of a inline declared field symbol is assigned.

If someone has a light about this I'll appreciate.


Thank you in advance.

Update1: More examples given. Output given.

Add comment
10|10000 characters needed characters exceeded

  • ABAP 7.5 SP 6.

    If the program I wrote didn’t have the same output in your system, please tell.

  • 7.52 SP 0, same result:
    
    Example1 - Loop 1
    SY-SUBRC =  4. Not assigned, as expected.
    Example2 - Loop 2
    SY-SUBRC =  4. Not assigned, as expected.
    Example3 - Loop 3
    SY-SUBRC =  4. Assigned!
    Example4 - Read 1
    SY-SUBRC =  4. Not assigned, as expected.
    Example5 - Read 2
    SY-SUBRC =  4. Not assigned, as expected.
    Example6 - Read 3
    SY-SUBRC =  4. Assigned!
  • Excellent Finding !

  • Get RSS Feed

5 Answers

  • Best Answer
    Apr 03 at 11:27 AM

    If the compiler cannot determine the type, a field symbol declared inline is not only declared with TYPE any but is also assigned the constant space. Unfortunately, the inline declaration shows the same behavior as the obsolete variant of the FIELD-SYMBOLS statement without TYPE addition here. For reasons of downward compatibility, this lapse cannot be corrected any more. Check only sy-subrc and not IS ASSIGNED in such cases. IS ASSIGNED is not recommended anyway at this position.

    Add comment
    10|10000 characters needed characters exceeded

  • Apr 03 at 06:00 AM

    Look at this:

    TYPES line TYPE t100.
    DATA itab TYPE STANDARD TABLE OF line WITH EMPTY KEY.
    FIELD-SYMBOLS <itab> TYPE STANDARD TABLE.
    ASSIGN itab TO <itab>.
    
    FIELD-SYMBOLS <line1> TYPE line. "<line1> is not assigned
    READ TABLE <itab> ASSIGNING <line1> INDEX 1.
    IF <line1> IS ASSIGNED.
      BREAK-POINT.
    ELSE.
      BREAK-POINT. "<line1> is still not assigned as documented
    ENDIF.
    
    FIELD-SYMBOLS <line2>. "<line2> points to constant space as documented
    READ TABLE <itab> ASSIGNING <line2> INDEX 1.
    IF <line2> IS ASSIGNED.
      BREAK-POINT. "<line2> still points to constant space as documented
    ELSE.
      BREAK-POINT.
    ENDIF.
    
    READ TABLE <itab> ASSIGNING FIELD-SYMBOL(<line3>) INDEX 1.
    IF <line3> IS ASSIGNED.
      BREAK-POINT. "<line3> points to constant space !!!
    ELSE.
      BREAK-POINT.
    ENDIF.
    

    The first two READs work as documented. <line1> and <line2> keep their assignment:

    • <line1> stays unassigned.
    • <line2> still points to constant space that comes from obsolete FIELD-SYMBOLS statement without TYPE addition.

    Now the the problem is drilled down to the question: Why does the inline declaration of the third READ statement mimic the obsolete declaration behavior of the FIELD-SYMBOLS statement?

    It does not happen, if itab is used in the READ statement instead of <itab>.

    Question forwarded to development.

    I keep you informed.

    Add comment
    10|10000 characters needed characters exceeded

  • Mar 29 at 09:26 AM

    That is quite unexpected, but documented behavior. Quote from inline FIELD-SYMBOL declaration:

    "...declares a field symbol <fs> to which a memory area is assigned in the current operand position."

    + of course:

    "The declaration is made when the program is compiled, regardless of whether the statement is actually executed."

    So the field symbol is assigned even before actual READ TABLE statement in your example.

    EDIT: I see there is difference in typed table and generic table, hmm don't know about that.

    Add comment
    10|10000 characters needed characters exceeded

  • Apr 02 at 03:13 PM

    I smell a bug.

    If the code is simplified to the minimum, the two programs below should be identical and behave identically (note that the inline field symbol <FS_TABLE4> in the second program refers implicitly to a one character field, because <standard_table> is a generic table type with no line type, and this is normal). BUT the second one fails.

    This first program gives a field symbol NOT assigned, as expected:

    REPORT ZPROGRAM1.
    FIELD-SYMBOLS <standard_table> TYPE STANDARD TABLE.
    DATA gt_table TYPE STANDARD TABLE OF flag WITH DEFAULT KEY.
    FIELD-SYMBOLS <fs_table4> TYPE flag.
    
    ASSIGN gt_table TO <standard_table>.
    READ TABLE <standard_table> ASSIGNING <fs_table4> INDEX 1.
    ASSERT <fs_table4> IS NOT ASSIGNED. " <========= NOT ASSIGNED AS EXPECTED

    But this second program gives a field symbol assigned, unexpectedly. I don't understand why.

    REPORT ZPROGRAM2.
    FIELD-SYMBOLS <standard_table> TYPE STANDARD TABLE.
    DATA gt_table TYPE STANDARD TABLE OF flag WITH DEFAULT KEY.
    
    ASSIGN gt_table TO <standard_table>.
    READ TABLE <standard_table> ASSIGNING FIELD-SYMBOL(<fs_table4>) INDEX 1.
    ASSERT <fs_table4> IS NOT ASSIGNED. " <========= SHORT DUMP because the FS is assigned!

    @ Horst Keller, could you help us please, any hint?

    Add comment
    10|10000 characters needed characters exceeded

  • Apr 02 at 03:42 PM
    -2

    This is strange. Dynamic variable purpose is to not to allocate memory. This actually should not happen. I think your loop is empty that's it is making it like that. because it completes loop->endloop. Not sure though. Try putting you internal table with INITIAL SIZE 0.

    Add comment
    10|10000 characters needed characters exceeded