cobc refuses a concatenation expression with the figurative constant ZERO as an operand, such as "A" & ZERO or ZERO & ZERO, while "A" & SPACE and "A" & QUOTE work. The same check, in a smaller case, refuses any figurative constant beside a national literal.
cat1.cob (attached, free format):
IDENTIFICATION DIVISION.
PROGRAM-ID. CAT1.
PROCEDURE DIVISION.
DISPLAY "[" "A" & ZERO & "B" "]"
STOP RUN.
cobc -x -free -std=cobol2014 cat1.cob
3.2.0 and 3.3-dev r5751 both stop, exit 1, with
cat1.cob:4: error: only literals with the same category can be concatenated
and the source excerpt. cat2.cob gets the same error for VALUE "A" & ZERO & "B", ZERO & "B", SPACE & ZERO and VALUE N"A" & SPACE & N"B", and "only alphanumeric, utf-8, national or boolean literals may be concatenated" for ZERO & ZERO. The national line also draws cobc's -Wunfinished warning for national literals.
The program displays [A0B]. ISO/IEC 1989:2023 8.8.3.2 syntax rule 1 requires both operands to be of the same class "except that a figurative constant may be specified as one or both operands". By 8.8.3.3 general rule 1 a) and b) the result has the class of the other operand, or is alphanumeric when both are figurative constants, and by 8.3.3.6.4 general rule 3 a) the figurative constant is one character. The same in 2002 and in the 2014 FCD.
cb_concat_literals in cobc/tree.c first refuses any pair whose categories differ (x1->category != x2->category). cb_zero is built with CB_CATEGORY_NUMERIC and the other figurative constants with CB_CATEGORY_ALPHANUMERIC, so ZERO never matches an alphanumeric literal and no figurative constant matches a national one; ZERO & ZERO passes that test and then fails the next one. get_data_from_const already maps ZERO to '0', but cb_concat_literals refuses ZERO before that code is reached. concat_literals also takes the result's category from the left operand.
The attached n10-concat-figurative-zero.patch (against 3.3-dev r5751) makes cb_concat_literals give a figurative constant the other operand's category, or alphanumeric when both are, before the checks (NULL is still refused), and concat_literals builds the literal with that category. With a national operand, get_data_and_size_from_lit makes the figurative constant one national character, 00 20 for SPACE as the scanner stores N" ", and FF FF for HIGH-VALUE as MOVE HIGH-VALUE does; a MOVE SPACE to a PIC N item stores 20 20 today, so you may prefer another representation. B"1" & B"0" is still refused, because cobc builds B literals as numeric literals.
With the patch cat1 prints [A0B] and cat2 prints
[A0B] [0B] [00] [ 0]
NATIONAL OK
It adds the testsuite case "Concatenation with figurative constants" to run_misc.at, with ChangeLog entries in cobc/ and tests/. make check: 1373 expected, 9 skipped, 0 failed (1372 unpatched); the new test fails without the patch.
None that we found.
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 run 2026-11-04. cat1 is refused the same way with -std=default, cobol2002, cobol85, ibm and mf.