06-Jan-2009

COBOL cross platform difference?

Oh dear. Is this a COBOL compiler bug? Or is the older version on Alpha doing the wrong thing with the uninitialized variable? Note that if the compiler has been changed to take the other path of the IF statement if we are comparing against binary zeros, the compiler should at least issue an appropriate diagnostic telling us.

Versions are COBOL 2.9-1453 on OpenVMS IA64 V8.3-1H1 and COBOL 2.8-1286 on OpenVMS Alpha V7.3-2 (and yes, I know it's recommended practice to upgrade OpenVMS Alpha and compilers prior to porting, yet I can't make that happen here).


       IDENTIFICATION DIVISION.
       PROGRAM-ID. TESTIT.
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT XYZZY-FILE
                  ASSIGN XYZZY
                  ORGANIZATION SEQUENTIAL
                  FILE STATUS FS.
       DATA DIVISION.
       FILE SECTION.
       FD XYZZY-FILE
          LABEL RECORDS ARE STANDARD
          RECORD CONTAINS 4 CHARACTERS
          DATA RECORD IS XYZZY.
       01  XYZZY.
           03  B PIC S9(4).
       WORKING-STORAGE SECTION.
       01  FS PIC X(2).
       01  A PIC S9(7)V99.

       PROCEDURE DIVISION.
       0 SECTION.
       0-BEGIN.
           MOVE 1.00 TO A.
           IF A IS NOT LESS THAN B
                DISPLAY "CORRECT"
           ELSE
                DISPLAY "INCORRECT".
           MOVE ZEROS TO B.
           IF A IS NOT LESS THAN B
                DISPLAY "CORRECT"
           ELSE
                DISPLAY "INCORRECT".

A run on Alpha versus IA64 produces the following:


Alpha> cobol/ansi/warnings=all test
Alpha> link test
Alpha> r test
CORRECT
CORRECT
IA64> cobol/ansi/warnings=all test
IA64> link test
IA64> r test
INCORRECT
CORRECT

Posted at January 6, 2009 2:52 PM
Tag Set:
Comments

I don't remember the procise context and cannot check the exact syntax at the moment, but I've encountered something similar in PASCAL, where a character string is initialised to zeroes on Alpha and to spaces on Itanium.

Moral: always initiate variables to a specific value.

Posted by: SYSMGR at January 6, 2009 5:31 PM

I could not resist copying the code and trying it out on my new zcobol portable mainframe COBOL compiler. And as I suspected the generated HLASM code to PACK and CP the two fields is unpredictable since the B field is not initialized and different language and OS environments handle initialization of storage differently. z390 defaults to initializing all memory x'F3' and program load module undefined fields to x'F6'. So when I compile and execute the program using zcobol/z390 on Windows J2SE, the B field contains all x'F6' and the CP ends up failing on compare of 100 with 6666. If I specify z390 option NOINIT, then the PACK fails with 0C7 due to zeros in the uninitized B field.

Don Higgins
don@higgins.net
www.zcobol.org

Posted by: Don Higgins at January 7, 2009 12:17 AM

Hi Don,

Yes, in this simplified reproducer, the obvious problem is that the B field is uninitialized. In the real code, it's a little more complex: we have a PIC X field that's been repurposed as a PIC S9 field, and obviously uninitialized at that time. Of course, in the real code, the variable is inited by reading the record.

The real issue is that it worked on the old platform, and doesn't on the new...

Posted by: Jim Duff at January 7, 2009 5:54 AM

Duh. The addition of the /CHECK=DECIMAL to the COBOL command will uncover this coding error and produce a run time error of %SYSTEM-F-DECINV, decimal invalid operand when a comparison is performed against a uninitialized field on both platforms.

This is a far better solution than the code behaving differently on different platforms.

Posted by: Jim Duff at January 8, 2009 3:33 PM

Comments are closed