In the relax level hierarchy (-frelax-level-hierarchy) mode, it should be possible to redifine a level that previously appeared with a lower level number "on the same level". This is available at least in IBM COBOL.
Minimal example:
IDENTIFICATION DIVISION.
PROGRAM-ID. RELAX-REDEFINE.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-A.
03 WS-B.
04 FILLER PIC X.
02 WS-C REDEFINES WS-B. *> 02 redefines 03 level.
10 FILLER PIC X.
PROCEDURE DIVISION.
MOVE 'A' TO WS-B
DISPLAY WS-C
GOBACK.
END PROGRAM RELAX-REDEFINE.
We have already investigated the bug and found a possible solution, but a more detailed investigation of the proposed solution is still pending. The diff of the proposal will follow in the close future.
In the current GnuCOBOL (3.2-rc2) implementation (
field.c#540) for the event ofwith relaxed level hierarchy, the tree is transformed to
in order to keep the level numbers. This leads to a problem in the moment of redefining
WS-BfromWS-C, becauseWS-Ccannot find it on the same tree level anymore. Our proposed solution does not add the additional"FILLER 1", instead it transforms the tree to representThis way
WS-Bcan be reached fromWS-C, although some level numbers are changed. However, this should not lead to any problems, since if there were an 02-level aboveWS-B,WS-Cshould not be able to redefineWS-B(same situation as with"FILLER 1", but this time intended and not valid).One could discuss whether it is necessary to change the level numbers at all, since one could theoretically also set
WS-B->sistertoWS-Cand slightly adjust the "if for the same level numbers in REDEFINES", but this could bring possible (later) problems, since in the datastructure tree two elements are on the same tree level, but not on the same COBOL level.Last edit: Chris G 2023-02-20
What about:
?
Currently we include a single filler which solves the problem, but I guess you now move all WS-Bs to the level 02, right?
It seems that all you really want is to prevent the error
right?
In this case the explicit check in field.c around line 660 is the one to adjust, possibly depending on
cb_indirect_redefinesand/orcb_relax_level_hierarchy, no?Exactly, in this case we would raise all
WS-B*to 02. We also looked atcb_indirect_redefines, but that is a different setting. Indirect redefines allowsAto be redefined byBandBbyC(so a kind of chain of redefinitions). So something like this:The problem with
field#652-660and why we adjusted it in the other place is that atfield#660one no longer has information about the fact that"FILLER 1"was inserted by cobc and not by the user (at least we had not seen any source of information).For example a user might write
which should result in an error, but only if the user inserted the
FILLER, not if cobc inserted it. So we figured, instead of creating a complex decision tree there, we look at where the filler level is inserted.Are you sure that
results in an error with IBM, but
doesn't? Sigh, at least that's the case with MicroFocus, the second compiles but the first raises:
I see. One thing that would be possible and may be useful in any case (also for the other places where we build an "internal filler" is to add a
flag_internal_fieldtocb_field; and usef->parent->flag_internal_fieldto decide about the error message.Yeah, the first example results in an error:
whereas the second doesn't... I reacted the same way when we tried that out.
I agree, such a flag would probably be useful for future references. I did a little digging in the code and
cb_build_filleris called a few times, although I stumbled upon a few more places where cobc builds a tree without fillers (e.g.cb_build_debug_itemorcb_validate_program_data), would they qualify asflag_internal_field = 1too? There are some obvious places where cobc adds/builds an additional tree (parser.y#7711), but there are also some places which represent a huge call hierarchy maybe returningFILLER(e.g.cb_name_1, whereas I don't know where the result of this would be used in). I don't know if the effort would be worth it to implement the flag properly or having a "mostly unused flag".Although I (personally) don't like the "changing the level numbers" method in our proposal, I think it won't break anything, since it only effects this (admittedly weird usage: redefining with relaxed level hierarchy) situation.