Cobol v6.2 NUMCHECK option compatibility

2.9k Views Asked by At

We can't turn off the NUMCHECK option for our new COBOL V6.2 compiler because we can't trust the content of our numeric variables. When we turn it on, it's not fully compatible with the COBOL 4 we had previously at our organization.

When an unsigned packed variable contains X'123C' , COBOL 4 would have accepted it and let us continue, but COBOL 6.2 with NUMCHECK(PAC,ABD) abends, and only willing to accept X'123F'. This is a real issue for us regarding assembler invoking COBOL, or reading from files and etc. Is there another option or maybe even a PTF that corrects this behavior? Can you point us to other incompatibilities like this one when NUMCHECK is on, if they exist? Thank you! Zohar

2

There are 2 best solutions below

3
On

This is working as documented. I know that's not what you wanted to hear, but sometimes that's just the way it is. Your application is abending because the NUMCHECK compile option has detected what it sees as invalid data.

Note that the NUMCLS installation option for IBM COBOL 6.2 governs the behavior of the IF NUMERIC class test, an implicit version of which is generated by the NUMCHECK compile option. If your packed data is defined without sign, i.e.

77  XYZ  PIC 999 COMP-3.

then the documentation indicates a sign nibble of x'F' is the only sign nibble which will pass an IF NUMERIC class test. Any other value for the sign nibble is considered invalid.

Excerpt from IBM Documentation for Enterprise COBOL 6.2...

Table 1. NUMCLS(PRIM) and valid signs

         NUMPROC(NOPFD) NUMPROC(PFD)
Signed   C, D, F        C, D, +0 (positive zero)  
Unsigned F              F

Table 2. NUMCLS(ALT) and valid signs

         NUMPROC(NOPFD) NUMPROC(PFD)
Signed   A to F         C, D, +0 (positive zero)  
Unsigned F              F

The wording for the documentation for the NUMCLS option for IBM COBOL 4.2 is definitely different...

Processing with ALT accepts hexadecimal A through F as valid.

Processing with PRIM accepts hexadecimal C, D, and F as valid.

You might want to check at https://www.ibm.com/support/pages/node/604539#112918 to see if any of the PTFs apply to your situation.

You could attempt to raise an issue with IBM, but here's the problem: if you have unsigned data, then an argument can be made that having a sign nibble indicating a positive (x'C') or negative (x'D') sign is invalid. I suspect this is part of the reason the NUMCHECK option works the way it does.

Possible solutions include having your Assembler programs invoking your COBOL programs do a sign fix on any packed data they pass. Maybe an OI on the last byte. You might be able to write control cards for your shop's SORT utility to fix packed data in your flat files. You could change your unsigned packed data items in your COBOL programs to be signed.

It all depends on what behavior you desire. You say you cannot trust the content of your numeric variables. If that means you sometimes have a sign nibble of x'A' instead of x'C' for a positive value, you can use NUMPROC(NOPFD) if NUMCLS(ALT) is in effect.

Another possible solution to your situation, if NUMCLS(ALT) is in effect, is to compile with NUMPROC(NOPFD) and use signed fields to initially hold your data. According to the documentation, moving the data to an unsigned field will fix the sign. Note that NUMPROC(NOPFD) does not perform as well as NUMPROC(PFD).

Following is an expansion of my understanding of the documentation of which sign nibbles result in an IF NUMERIC test being true. I have no way to test this, it's just my attempt to translate the documentation's implicit language into an explicit table. It does highlight the differences between IBM Enterprise COBOL 4.x and IBM Enterprise COBOL v5 and later.

                      SIGN   COBOL 5+ COBOL 4
NUMCLS NUMPROC SIGNED NIBBLE NUMERIC  NUMERIC
ALT    NOPFD   YES    X'A'   TRUE     TRUE
ALT    NOPFD   YES    X'B'   TRUE     TRUE
ALT    NOPFD   YES    X'C'   TRUE     TRUE
ALT    NOPFD   YES    X'D'   TRUE     TRUE
ALT    NOPFD   YES    X'E'   TRUE     TRUE
ALT    NOPFD   YES    X'F'   TRUE     TRUE
ALT    NOPFD   NO     X'A'   FALSE    TRUE
ALT    NOPFD   NO     X'B'   FALSE    TRUE
ALT    NOPFD   NO     X'C'   FALSE    TRUE
ALT    NOPFD   NO     X'D'   FALSE    TRUE
ALT    NOPFD   NO     X'E'   FALSE    TRUE
ALT    NOPFD   NO     X'F'   TRUE     TRUE
ALT    PFD     YES    X'A'   FALSE    FALSE
ALT    PFD     YES    X'B'   FALSE    FALSE
ALT    PFD     YES    X'C'   TRUE     TRUE
ALT    PFD     YES    X'D'   TRUE     TRUE
ALT    PFD     YES    X'E'   FALSE    FALSE
ALT    PFD     YES    X'F'   FALSE    FALSE
ALT    PFD     NO     X'A'   FALSE    FALSE
ALT    PFD     NO     X'B'   FALSE    FALSE
ALT    PFD     NO     X'C'   FALSE    FALSE
ALT    PFD     NO     X'D'   FALSE    FALSE
ALT    PFD     NO     X'E'   FALSE    FALSE
ALT    PFD     NO     X'F'   TRUE     TRUE
PRIM   NOPFD   YES    X'A'   FALSE    FALSE
PRIM   NOPFD   YES    X'B'   FALSE    FALSE
PRIM   NOPFD   YES    X'C'   TRUE     TRUE
PRIM   NOPFD   YES    X'D'   TRUE     TRUE
PRIM   NOPFD   YES    X'E'   FALSE    FALSE
PRIM   NOPFD   YES    X'F'   TRUE     TRUE
PRIM   NOPFD   NO     X'A'   FALSE    FALSE
PRIM   NOPFD   NO     X'B'   FALSE    FALSE
PRIM   NOPFD   NO     X'C'   FALSE    TRUE
PRIM   NOPFD   NO     X'D'   FALSE    TRUE
PRIM   NOPFD   NO     X'E'   FALSE    FALSE
PRIM   NOPFD   NO     X'F'   TRUE     TRUE
PRIM   PFD     YES    X'A'   FALSE    FALSE
PRIM   PFD     YES    X'B'   FALSE    FALSE
PRIM   PFD     YES    X'C'   TRUE     TRUE
PRIM   PFD     YES    X'D'   TRUE     TRUE
PRIM   PFD     YES    X'E'   FALSE    FALSE
PRIM   PFD     YES    X'F'   FALSE    FALSE
PRIM   PFD     NO     X'A'   FALSE    FALSE
PRIM   PFD     NO     X'B'   FALSE    FALSE
PRIM   PFD     NO     X'C'   FALSE    FALSE
PRIM   PFD     NO     X'D'   FALSE    FALSE
PRIM   PFD     NO     X'E'   FALSE    FALSE
PRIM   PFD     NO     X'F'   TRUE     TRUE
0
On

I don't have the reputation yet to add a comment, so I'll have to add another answer. I'm one of the Enterprise COBOL developers though, and what I can say is that the V4.2 docs are a little less clear and the wording has been changed for V6, but the behaviour of the compiler has not. The behaviour both compilers use matches the V5 column in cschneid's table above.

For numeric class tests, unsigned packed and zoned data items always require a sign of x'F', no matter what the NUMPROC or NUMCLS settings are. Signed items allow C and D always, F with NUMPROC(NOPFD) (regardless of the NUMCLS setting), and A, B, and E only for NUMCLS=ALT,NUMPROC(NOPFD). The documentation in the customization guide for NUMCLS is only talking about signed class tests.

As for the original issue: NUMCHECK behaves exactly like an IS NUMERIC test, and in both cases, a sign of x'C' is considered invalid for an unsigned data item and an IS NUMERIC test or NUMCHECK will find the value not numeric/invalid. The behaviour you get for all other COBOL statements (compares, arithmetic, MOVEs, etc.) with a sign of x'C' is undefined under NUMPROC(PFD) and may vary between V4/V6, between OPT levels in V6, between ARCH levels in V6, etc. Under NUMPROC(NOPFD) and in some cases NUMPROC(MIG) in V4 (MIG is unsupported in V6), the sign of an unsigned item is forced to 0xF before the value in that data item is used, so this guarantees a certain behaviour, as well as behavioural compatibility. NUMCHECK however, is made to match the IS NUMERIC class test and also to find invalid data so it can be corrected (otherwise there's no point using NUMCHECK, as the tests it adds to your program will negatively impact performance), so it's going to flag all invalid data, even data that seemed to "work correctly" in V4 (which really means that while the behaviour under NUMPROC(PFD) is undefined, it was at least consistent).