0 ** 0 is not treated as a size error in two cases. When both operands are literals, cobc folds it to 1 at compile time and the NOT ON SIZE ERROR phrase runs. When the operands are data items, the SIZE ERROR phrase runs, but the receiving item is still overwritten with 1. The standard says 0 raised to the power 0 is a size error and the receiver must keep its old value.
cfpow0.cob (attached) computes 0 ** 0 on literals:
IDENTIFICATION DIVISION.
PROGRAM-ID. CFPOW0.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 R PIC S9(5) VALUE 77.
PROCEDURE DIVISION.
COMPUTE R = 0 ** 0
ON SIZE ERROR DISPLAY "SIZE ERROR, R=" R
NOT ON SIZE ERROR DISPLAY "NO SIZE ERROR, R=" R
END-COMPUTE
STOP RUN.
cobc -std=cobol2014 -x cfpow0.cob && ./cfpow0
sepow0.cob (attached) is the same program with 01 Z PIC S9(5) VALUE 0. added and COMPUTE R = Z ** Z in place of 0 ** 0 (PROGRAM-ID SEPOW0).
Output on 3.2.0 (run exit 0):
NO SIZE ERROR, R=+00001
The output is the same with the default dialect (no -std). With -fno-constant-folding added, the output is (run exit 0):
SIZE ERROR, R=+00001
3.3-dev r5751 gives byte-identical output for all three builds (folding, default dialect, -fno-constant-folding), run exit 0.
Output of cobc -std=cobol2014 -x sepow0.cob && ./sepow0 on 3.2.0 (run exit 0):
SIZE ERROR, R=+00001
The output is the same with the default dialect. 3.3-dev r5751 gives the same output, byte-identical, in both dialects (run exit 0).
Both programs should print SIZE ERROR, R=+00077: the size error condition exists, the SIZE ERROR phrase runs, and R keeps 77. ISO/IEC 1989:2023 says this (the 2014 and 2002 editions have the same rules; in their numbering the exponentiation rule is 8.8.1.1):
So the fold in the literal case should not happen (or should produce the size error), and in the data-item case the receiving item should not be stored.
In cb_build_binary_op (cobc/tree.c), the constant-folding arm case '^' declines to fold a negative exponent but folds 0 ** 0 to 1. That is the literal case. The run-time case is in cob_decimal_pow, which stores 1 for 0 ^ 0 instead of setting the result to NaN with EC-SIZE-EXPONENTIATION. patches #66 already fixes that part.
The attached zero-power-zero.patch (against 3.3-dev r5751, applies with patch -p1 at the top of the tree) covers the part patches #66 does not. In cb_build_binary_op (cobc/tree.c), the folding arm case '^' now also declines to fold when both base and exponent are 0, as it already does for a negative exponent. So 0 ** 0 on literals is computed by cob_decimal_pow at run time, like the data-item case. The run-time store of 1 is what patches #66 fixes in cob_decimal_pow, so this patch does not touch libcob.
With this patch alone, cfpow0 takes the same run-time path as sepow0 (cobc -std=cobol2014 -x, default dialect and -fno-constant-folding alike, run exit 0):
SIZE ERROR, R=+00001
With this patch and the intrinsic.c part of patches #66 (which still applies to r5751, hunk 3 at offset 24), both programs give the expected result in all three builds (run exit 0):
SIZE ERROR, R=+00077
make check on 3.3-dev r5751 with the patch (without patches #66): 1373 behaved as expected, 9 skipped, 0 failed, as unpatched (1372) plus the new test 611, which passes; unpatched it prints SIZE ERROR not set from 0 ** 0!. The patch adds the test "COMPUTE 0 ** 0 literal with SIZE ERROR" to tests/testsuite.src/run_fundamental.at (after "Numeric operations (8)"; it also checks that 0 ** 1 and 5 ** 0 still give 0 and 1 without a size error, with and without -fno-constant-folding) and a cobc/ChangeLog entry.
cob_decimal_pow, which would fix the data-item case.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. Both programs are fixed format. Every compile exits 0 with no cobc diagnostic. 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.