Menu ▾ ▴

#1278 MOVE to numeric-edited replaces a comma left of every digit position (PIC ,999)

GC 3.x
open
nobody
None
5 - default
2026-10-30
2026-10-30
No

A comma at the start of a numeric-edited picture, such as PIC ,999, is printed as a space. The standard says a comma in that position is simple insertion, so it should appear in the output. Programs that print amounts or codes with a leading comma get the wrong text on both 3.2.0 and 3.3-dev, and with DECIMAL-POINT IS COMMA the same happens to a leading period.

To reproduce

lcomma.cob (attached) moves values into four edited items and displays them:

IDENTIFICATION DIVISION.
PROGRAM-ID. LCOMMA.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 E1 PIC ,999.
01 E2 PIC $,ZZZ,ZZ9.99.
01 E3 PIC ,***.
01 E4 PIC 0ZZ9.
PROCEDURE DIVISION.
    MOVE 12 TO E1
    MOVE 123.45 TO E2
    MOVE 12 TO E3
    MOVE 12 TO E4
    DISPLAY "[" E1 "]"
    DISPLAY "[" E2 "]"
    DISPLAY "[" E3 "]"
    DISPLAY "[" E4 "]"
    STOP RUN.
cobc -x -free -std=cobol2014 lcomma.cob && ./lcomma

lperiod.cob (attached) has DECIMAL-POINT IS COMMA in SPECIAL-NAMES, 01 E1 PIC .999., MOVE 12 TO E1 and DISPLAY "[" E1 "]". It is built and run the same way.

What happens

Every compile exits 0 with no cobc diagnostic. On 3.2.0 the output is below, and the default dialect gives the same:

[ 012]
[$     123.45]
[ *12]
[0 12]

3.3-dev r5751, same command, run exit 0:

[ 012]
[$     123.45]
[**12]
[0 12]

The comma is replaced by a space in E1 and E2 on both versions. In E3 it is replaced by a space on 3.2.0 and by an asterisk on 3.3-dev. The 0 in E4, in the same position, is kept.

With DECIMAL-POINT IS COMMA, lperiod.cob on 3.2.0 (cobc -x -free -std=cobol2014 lperiod.cob && ./lperiod, run exit 0):

[ 012]

3.3-dev r5751 gives the same output, run exit 0.

What should happen

The commas stay:

[,012]
[$,    123.45]
[,*12]
[0 12]

and lperiod.cob prints [.012]. ISO/IEC 1989:2023 says (the 2014 edition has the same rules):

  • §13.18.40.4 general rule 14: "Each symbol ',' (comma) represents a character position into which the character comma will be inserted during editing."
  • §13.18.40.5 rule 3 (simple insertion editing, symbols B 0 / and comma): "Simple insertion editing results in the insertion character occupying the same character position in the edited item as the associated symbol occupies in character-string-1."
  • §13.18.40.5 rule 7: "Zero suppression with replacement is indicated by specifying a string of one or more identical zero-suppression characters. Any of the simple insertion editing symbols embedded in this string or to the immediate right of this string are part of the string."

A comma to the left of the Z or * string is not part of it, and PIC ,999 has no zero suppression at all, so the comma stays. The commas inside ZZZ,ZZ9 are part of the Z string and are replaced as they are now.

Proposed fix

The attached numeric-edited-comma-insertion.patch is against 3.3-dev r5751 and applies with patch -p1 at the top of the tree. It changes optimized_move_display_to_edited, so it does not apply to 3.2's cob_move_display_to_edited.

In optimized_move_display_to_edited (libcob/move.c) the Z and * arms now set a new flag, have_zero_suppression. The '.' / ',' arm replaces a separator that is not the decimal point only while zeroes are suppressed AND a floating insertion string (prev_float_char) or a Z / * has been met to its left. A separator left of every such symbol is simple insertion and is now kept. Separators inside or right of the Z, * or floating string are handled as before. The all-zero results (spaces for Z, asterisks for *) still come from the code after the loop.

With the patch, cobc -x -free -std=cobol2014 lcomma.cob && ./lcomma (the same in the default dialect), run exit 0:

[,012]
[$,    123.45]
[,*12]
[0 12]

cobc -x -free -std=cobol2014 lperiod.cob && ./lperiod (the same in the default dialect), run exit 0:

[.012]

make check on 3.3-dev r5751 with the patch: 1373 behaved as expected, 9 skipped, 0 failed, as unpatched (1372) plus the new test 553, which passes; unpatched it prints 012 for PIC ,999. The patch adds the test "MOVE to item with comma left of zero suppression" to tests/testsuite.src/run_fundamental.at (after "MOVE to item with +, -, B, 0, / and ,"; it also checks PIC +,999, PIC ,ZZZ with 1 and 0, and PIC ,*** with 0) and a libcob/ChangeLog entry.

  • #1008 (closed): fixed wrong replacement characters for insertion symbols inside or right of a floating string in the same routine. This case is a comma left of every digit position.

Details

GnuCOBOL 3.2.0 (Ubuntu gnucobol3 3.2-4build1) and 3.3-dev r5751 (CI snapshot 3.3-dev.138 of 2026-10-29), x86_64 Linux, both re-run 2026-10-30. On 3.2.0 the Ubuntu C compiler step also prints <command-line>: warning: ‘_FORTIFY_SOURCE’ redefined and its note; that is the distribution's build setting, and it is left out above.

3 Attachments

Discussion


Log in to post a comment.