Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

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

ffs
Explorer

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.

1 ACCEPTED SOLUTION

horst_keller
Product and Topic Expert
Product and Topic Expert

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.

22 REPLIES 22

Tomas_Buryanek
Active Contributor

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.

-- Tomas --

0 Kudos

Hi FFS,

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

Regards,


0 Kudos

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 Kudos

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 Kudos

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

0 Kudos

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

horst_keller
Product and Topic Expert
Product and Topic Expert

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

Sandra_Rossi
Active Contributor
0 Kudos

What is your ABAP release and SP ?

ffs
Explorer

ABAP 7.5 SP 6.

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

Sandra_Rossi
Active Contributor
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!

Sandra_Rossi
Active Contributor

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?

horst_keller
Product and Topic Expert
Product and Topic Expert

Thanks for notifying,

kasralikarpratik
Explorer
0 Kudos

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.

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).

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

horst_keller
Product and Topic Expert
Product and Topic Expert

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.

0 Kudos

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.

horst_keller
Product and Topic Expert
Product and Topic Expert

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.

It’s unfortunate that it cannot be corrected.

Question solved.

horst_keller
Product and Topic Expert
Product and Topic Expert

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.

0 Kudos

Question solved, thank you.

Excellent Finding !