not/truncate on MOVE to S9(4) BINARY

The Lounge
2014-02-27
2014-03-14
  • Juergen Weber
    Juergen Weber
    2014-02-27

    Hello,

    I found that there is a subtle semantic difference in MOVEs to S9(4) BINARY between Enterprise COBOL for z/OS and Gnu Cobol.

    Enterprise COBOL also truncates on moving to an S9(4) whereas Gnu Cobol only truncates on display.

    I wonder which one is correct. I append a sample and sample outputs.

    Greetings, Juergen

           IDENTIFICATION DIVISION.
           PROGRAM-ID. "S4".
           ENVIRONMENT DIVISION.
           CONFIGURATION SECTION.
           SOURCE-COMPUTER.  IBM-370 WITH DEBUGGING MODE.
           DATA DIVISION.
           WORKING-STORAGE SECTION.
           01  x0             PICTURE S9(4) BINARY.
           01  x01            PICTURE S9(4) BINARY.
           01  x02            PICTURE S9(4) BINARY.
           01  x1             PICTURE S9(5) BINARY.
    
           PROCEDURE DIVISION.
                move 30000 to x01
                move 2767 to x02
                display "x01: " x01
                display "x02: " x02
                ADD x01 TO x02 GIVING x1.
                display x1
                display "---"
    
                move 8000 to x01
                move 2767 to x02
                display "x01: " x01
                display "x02: " x02
                ADD x01 TO x02 GIVING x1.
                display x1
                display "---"
    
                move 10000 to x0
                move x0 to x1
                display x1
    
                STOP RUN.
    

    results:

    ~ cob2 s.cbl
     PP 5655-G53 IBM Enterprise COBOL for z/OS  3.3.0 in progress ...
     End of compilation 1,  program AE,  no statements flagged.
    ~ a.out
    x01: 0000
    x02: 2767
    02767
    ---
    x01: 8000
    x02: 2767
    10767
    ---
    00000
    

    =======================

    weberjn:~ ./s
    x01: +0000
    x02: +2767
    +32767
    ---
    x01: +8000
    x02: +2767
    +10767
    ---
    +10000
    
    weberjn:~ cobc -V
    cobc (GNU Cobol) 1.1.0
    Copyright (C) 2001,2002,2003,2004,2005,2006,2007 Keisuke Nishida
    Copyright (C) 2006-2012 Roger While
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    Built     Feb 14 2014 11:04:32
    Packaged  Jan 20 2014 07:40:53 UTC
    C version "4.1.2 20080704 (Red Hat 4.1.2-54)"
    
     
    Last edit: Simon Sobisch 2014-04-28
  • Bill Woodger
    Bill Woodger
    2014-02-28

    I guess you are compiling on z/OS with TRUNC(STD). 3.3 is very old by the way, but you probably know that:-)

    The behaviour shown on GNU COBOL looks like what you'd get with TRUNC(OPT) and breaking the rules (allowing a value beyond the maximum value of the PICture). If you do that with TRUNC(OPT) the results are undefined.

    With TRUNC(OPT) you enter into a contract with the compiler not to exceed the values represented by the PICture.

    TRUNC(OPT) will truncate on DISPLAY. Otherwise the compiler generates code which would truncate to either field-size (binary truncation) or PICture (decimal truncation) whichever is the most convenient at the time. As long as values don't exceed the PICture, this is unproblematic.

    Whether this is co-incidence, or intended behaviour of GNU COBOL I can't say.

    However, assuming that binary is non-native, then it is just wrong to stuff too much into a 9(4). Unless the DISPLAY from GNU COBOL is buggy, your binary in that compile is non-native.

    For some reason Entrprise COBOL allows the MOVE of a literal value greater thn the PICture. Seems GNU COBOL does as well.

    I'd extend the test, making a 9(5) to hold the 30,000, and then MOVE the 9(5) to the 9(4). If that causes a repeat of your results, I'd say it was a problem. If not, not a problem (unless unintended), but something to be resolved by documentation of what happens.

    Good spot, as somewhere along the way someone will be tearing their hair out over something like this - now a quick search, and they'll find your post.

     
    Last edit: Bill Woodger 2014-02-28
  • Luke Smith
    Luke Smith
    2014-03-03

    There are several GNU Cobol configuration variables that control this.

    Look in the GNU Cobol 2.0 Programmers Guide for 8.1.6. Using Compiler Configuration Files. And also 8.4. Binary Truncation.

    There are several configuration files to choose from. If one can't be found that solves the issue, they can be modified, or a new one created on your site. See /usr/local/share/gnu-cobol/config on Linux.

    I always set binary truncate to no. If I need to truncate numbers I always use display type numbers, not binary. The extra overhead of checking limits of binary numbers is not desirable.

    binary-truncate: no

    There's another setting to make the amount of memory allocated the same as IBM MVS or more like Microfocus or others.

    Update these and try the above issue again.

     
  • Juergen Weber
    Juergen Weber
    2014-03-05

    Thanks for your contributions so far.

    I changed the test a bit, and did not change the default Gnu Cobol options.

    I understand now the IBM cobol output, but I don't understand why Gnu Cobol's last two outputs are how they are, I think, they should be like IBM's.

           IDENTIFICATION DIVISION.
           PROGRAM-ID. "AE".
           ENVIRONMENT DIVISION.
           CONFIGURATION SECTION.
           SOURCE-COMPUTER.  IBM-370 WITH DEBUGGING MODE.
           DATA DIVISION.
           WORKING-STORAGE SECTION.
           01  s4             PICTURE S9(4) BINARY.             
           01  s41            PICTURE S9(4) BINARY.             
           01  s42            PICTURE S9(4) BINARY.             
           01  s5             PICTURE S9(5) BINARY.             
           01  s51            PICTURE S9(5) BINARY.             
           01  s52            PICTURE S9(5) BINARY.             
    
           PROCEDURE DIVISION.
                move 25000 to s51
                move 16000 to s52
                ADD s51 TO s52 GIVING s5.
                display "s51: " s51
                display "s52: " s52
                display "ADD s51 TO s52 GIVING s5."
                display "s5: " s5
                display "MOVE s51 to s41, s52 to s42"
                display "ADD s41 TO s42 GIVING s4"
    
                move s51 to s41
                move s52 to s42
                ADD s41 TO s42 GIVING s4.
                display "s41: " s41
                display "s42: " s42
                display "s4: " s4
                display "---"
    
                move 10000 to s4
                move s4 to s5
                display s5
    
                STOP RUN.
    

    IBM output:

    s51: 25000
    s52: 16000
    ADD s51 TO s52 GIVING s5.
    s5: 41000
    MOVE s51 to s41, s52 to s42
    ADD s41 TO s42 GIVING s4
    s41: 5000
    s42: 6000
    s4: 1000
    ---
    00000
    

    Gnu Cobol output:

    s51: +25000
    s52: +16000
    ADD s51 TO s52 GIVING s5.
    s5: +41000
    MOVE s51 to s41, s52 to s42
    ADD s41 TO s42 GIVING s4
    s41: +5000
    s42: +6000
    s4: +0000
    ---
    +10000
    
     
    Last edit: Simon Sobisch 2014-04-28
  • Stefan Bodingh
    Stefan Bodingh
    2014-03-06

    Micro Focus COBOL output is the same as IBM output.

     
  • Juergen Weber
    Juergen Weber
    2014-03-06

    Thanks, Stefan.
    Looks like I should file a bug ..
    But I'll wait a few days, to leave time for more comments.

     
  • Just run it on MVS v3.8J using ANSI Cobol CB545 V2 LVL78 01MAY72

    Also had to change some thing so here is the list and results:

    CB545 V2 LVL78 01MAY72 IBM OS AMERICAN NATIONAL STANDARD COBOL DATE MAR 14,2014
    1
    00001 IDENTIFICATION DIVISION.
    00002 PROGRAM-ID. AE.
    00003 ENVIRONMENT DIVISION.
    00004 CONFIGURATION SECTION.
    00005 SOURCE-COMPUTER. IBM-370.
    00006 OBJECT-COMPUTER. IBM-370.
    00007 DATA DIVISION.
    00008 WORKING-STORAGE SECTION.
    00009 01 S4 PICTURE S9(4) COMP.
    00010 01 S41 PICTURE S9(4) COMP.
    00011 01 S42 PICTURE S9(4) COMP.
    00012 01 S5 PICTURE S9(5) COMP.
    00013 01 S51 PICTURE S9(5) COMP.
    00014 01 S52 PICTURE S9(5) COMP.
    00015
    00016 PROCEDURE DIVISION.
    00017 MOVE 25000 TO S51
    00018 MOVE 16000 TO S52
    00019 ADD S51 TO S52 GIVING S5.
    00020 DISPLAY S51:  S51
    00021 DISPLAY S52:  S52
    00022 DISPLAY ADD S51 TO S52 GIVING S5.
    00023 DISPLAY S5:  S5
    00024 DISPLAY MOVE S51 TO S41, S52 TO S42
    00025 DISPLAY ADD S41 TO S42 GIVING S4
    00026
    00027 MOVE S51 TO S41
    00028 MOVE S52 TO S42
    00029 ADD S41 TO S42 GIVING S4.
    00030 DISPLAY S41:  S41
    00031 DISPLAY S42:  S42
    00032 DISPLAY S4:  S4
    00033 DISPLAY ---
    00034
    00035 MOVE 10000 TO S4
    00036 MOVE S4 TO S5
    00037 DISPLAY S5
    00038
    00039 STOP RUN
    

    output:

    S51: 25000
    S52: 16000
    ADD S51 TO S52 GIVING S5.
    S5: 41000
    MOVE S51 TO S41, S52 TO S42
    ADD S41 TO S42 GIVING S4
    S41: 5000
    S42: 6000
    S4: 453O
    ---
    
    10000
    

    Note that I changed usage BINARY for COMP as former not available.

    Compiler defaults (with stats):

    *STATISTICS* SOURCE RECORDS = 39 DATA DIVISION STATEMENTS = 6 PROCEDURE DIVISION STATEMENTS = 20
    *OPTIONS IN EFFECT* SIZE = 4194304 BUF = 2097152 LINECNT = 57 SPACE1, FLAGW, SEQ, SOURCE
    *OPTIONS IN EFFECT* NODMAP, NOPMAP, NOCLIST, SUPMAP, NOXREF, LOAD, NODECK, APOST, NOTRUNC, NOLIB, NOVERB
    *OPTIONS IN EFFECT* ZWB
    

    The compiler is a little older than yours on z/OS :)

     
    Last edit: Simon Sobisch 2014-04-28