When using a variable from an OCCURS table both as a source and as a target within a STRING operation, GNUCobol generates incorrect C code.
The generated code reuses the same temporary cob_field structure (f0) for multiple fields. As a result, the pointer inside the reused temporary field gets overwritten, causing incorrect behavior at runtime.
This leads to wrong string contents because the temporary field does not represent the correct source and target fields independently.
Example Sourcecode:
MOVE "1234" TO SYAWDR-SIGMA-TXT (1)
STRING KLAMMER-AUF DELIMITED SIZE
SYAWDR-SIGMA-TXT (1) DELIMITED SIZE
INTO D312-SIGMA-KOPF (1)
END-STRING
DISPLAY 1 " -> " SYAWDR-SIGMA-TXT (1)
Generated (incorrect) C code excerpt:
/* Line: 29 : MOVE : main.cob */
memcpy (b_17 + 2, "1234", 4);
/* Line: 30 : STRING : main.cob */
cob_string_init (COB_SET_FLD (f0, 7, b_17 + 6, &a_5), NULL);
cob_string_delimited (NULL);
cob_string_append (&f_18);
cob_string_delimited (NULL);
cob_string_append (COB_SET_FLD (f0, 4, b_17 + 2, &a_5));
cob_string_finish ();
/* Line: 34 : DISPLAY : main.cob */
cob_display (0, 1, 3, &c_4, &c_5, COB_SET_FLD (f0, 4, b_17 + 2, &a_5));
Here, the same temporary field f0 is used for both the source and the target inside the STRING operation, which causes the internal pointer to be overwritten.
Inside codegen.c, function output_stmt(), the variable stack_id is reset to 0 at the beginning of each call.
This forces code generation to reuse the same temporary cob_field (f0) instead of allocating separate temporaries for each field reference.
Removing the line resetting stack_id inside output_stmt() fixes the issue:
/ in codegen.c, inside function output_stmt() /
// stack_id = 0; // Removing this line fixes incorrect temporary field reuse
With this change, each field occurrence gets its own temporary cob_field, and STRING operations involving OCCURS items work correctly.
GNUCobol should generate separate temporary field structures for each referenced variable inside a STRING statement, even if the variables originate from the same OCCURS group.
The generated C reuses the same temporary structure (f0), causing pointer aliasing and incorrect results.
GNUCobol version: cobc (GnuCOBOL) 3.3-dev.0
Platform: Windows
Compiler: gcc version 15.1.0 (Rev6, Built by MSYS2 project)
I don't understand this bug description.
Could you please provide the complete data definitions with PICTURE clauses for SYAWDR-SIGMA-TXT, KLAMMER-AUF, and D312-SIGMA-KOPF, along with the initial contents or VALUE of KLAMMER-AUF?
Then could you also please provide what results you actually received in D312-SIGMA-KOPF, versus what you expected to find in D312-SIGMA-KOPF?
Kind regards,
Hi Arnold,
I’m sorry if my previous bug description wasn’t clear enough.
The complete source code I used is:
I expect the output to be:
but instead I get:
The reason becomes clear when looking at the generated C code:
f0 is used as the temporary structure for the target field but is overwritten when processing the second source operand. This changes the field, pointed to (as string target) and leads to the incorrect result.
Thank you very much for the additional information.
I think you may have a minor error in your sample program. The following statement:
DISPLAY 1 " -> " SYAWDR-SIGMA-TXT (1)
Should be replaced by one of these examples:
DISPLAY 1 " -> " AUSGABE (or)
DISPLAY 1 " -> " D312-SORT-TAB (or)
DISPLAY 1 " -> " D312-SIGMA-KOPF (1)
I do not have a very current version of GnuCOBOL 3.3 DEV. Mine comes from Chuck Haatvedt and has the following version:
I am unable to replicate your results. I have created a modified version of your sample program with two additional DISPLAY statements at the end (see attachments) and these are the results I get:
I have also tested the modified program with a 32-bit MinGW version of GnuCOBOL 3.2, and I get the same results:
If there is a more up-to-date build of GnuCOBOL 3.3 DEV 0 that will make the source field SYAWDR-SIGMA-TXT (1) have the corrupted value "1123" I would definitely call that a bug.
Kind regards,
Last edit: Arnold Trembley 2025-12-08
Hi,
I recently updated to GNUCobol 4.0, and the issue no longer persists.
For me, the problem is resolved and this ticket can be closed.
Thank you very much for your time and for maintaining and improving GNUCobol — it is greatly appreciated.
We'd really like to fix it for GnuCOBOL 3.3 if it is reproducible there - is this possible for you?
I tested it on macOS 15.7.1 (ARM) with the latest 3.3 updates:
To be clear, I never checked the generated C code, because I am not well versed in C. I don't believe I can determine if there is a defect in the generation of the intermediate C code.
But I believe that the COBOL results are correct in all cases, using either c_main.cob or the similar bug1165v01.cbl (with extra display statements).