Skip to Content
6

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

Mar 28 at 09:06 PM

260

avatar image

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.

10 |10000 characters needed characters left characters exceeded

What is your ABAP release and SP ?

0

ABAP 7.5 SP 6.

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

1
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!
1

Excellent Finding !

1
* Please Login or Register to Answer, Follow or Comment.

5 Answers

Best Answer
Horst Keller
Apr 03 at 11:27 AM
3

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.

Show 1 Share
10 |10000 characters needed characters left characters exceeded

Question solved, thank you.

0
Horst Keller
Apr 03 at 06:00 AM
4

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.

Show 3 Share
10 |10000 characters needed characters left characters exceeded

I see.

"If no explicit type is specified after FIELD-SYMBOLS, the field symbol is typed implicitly with the fully generic type any. Also, the field symbol is assigned the predefined constant space when the context is loaded. This means that the field symbol is not initial directly after it has been declared, and a check using IS ASSIGNED is true."

Thank you for your insight, looking forward to see development team feedback.

0

The answer from development is, yes, it is a "slip of the pen", but it cannot be corrected because of downward compatibility reasons.

Therefore, 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. Sigh.

Documentation must be enhanced with that unpleasant fact.

You should check sy-subrc in such cases only.

2

It’s unfortunate that it cannot be corrected.

Question solved.

1
Tomas Buryanek Mar 29 at 09:26 AM
0

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.

Show 6 Share
10 |10000 characters needed characters left characters exceeded

Hi FFS,

Define field-symbols <fs_table> like line of gt_table[].

Regards,


0
ROBERTO Forti Santos

That is not the point... that is a previously declared field symbol.

0

Hi FFS,

Try this way.

...

field-symbols <fs_table> type any.

CREATE DATA gt_table TYPE STANDARD TABLE OF ty_table.

ASSIGN gt_table->* TO <fs_any_table>.

CLEAR gt_table.

CREATE DATA gt_table TYPE ty_table.

ASSIGN gt_table->* TO <fs_table>.

Regards,

0
ROBERTO Forti Santos

This is the same thing\problem... but thank you.

0

Yes, the difference is when accessing an internal table through a field symbol of type generic table type and assigning the field symbol itself to an inline declared field symbol.

0

The question is, why the inline declaration behaves like the obsolete variant of the FIELD-SYMBOLS statement, by initally assigning constant space.

1
Sandra Rossi Apr 02 at 03:13 PM
0

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?

Show 1 Share
10 |10000 characters needed characters left characters exceeded

Thanks for notifying,

1
Pratik Kasralikar 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.

Show 2 Share
10 |10000 characters needed characters left characters exceeded

It's the same. The purpose of my question it's not to find a solution (because I can always check sy-subrc) but to understand why this happens (and if it should happen).

1

It should not. Purpose of dynamic variable is to not to allocate any memory until value gets assigned to it. I think its bug.

1