Problem:
We have a programmer that experienced a problem on the host after testing in
Mainframe Express. MFE was placing low values in working storage fields while
animating, but the IBM mainframe was using residual values in working storage fields. Some of the fields in question had incorrect names and such. So, the mainframe was abending because the fields were not initialized.
Is there a way to keep Mainframe Express from tracking storage values?
Resolution:
The underlying issue here is really dealing with the contents of storage
items containing valid data at the time they are being referenced by
Procedure Division code. An explanation follows.
The DEFAULTBYTE directive in Mainframe Express should place Low Values into
Working Storage fields. And on the host IBM does this via an LE (Language
Environment) runtime option. IBM warns this takes a performance hit.
The best thing to do is use the INITIALIZE verb on any platform. The
INITIALIZE verb places Zeroes into numeric fields and Spaces into
alpha/alphanumeric fields. Since the INITIALIZE will work on multiple
platforms (z/OS, Windows, UNIX) it is the best solution.
The bulk of our data validation work has been for INT code since we expect
programmers to debug their user code with INT code and then use GNT
code for previously tested programs. So our default for GNT code is to not
check data values. However we are making incremental changes to GNT code
because of customer requests.
Actually, IBM has long documented that programs should validate data before
using it. See this strong statement from IBM in its VS Cobol II manual and
a weaker one from their z\\OS Compiler.
Title: VS COBOL II Application Programming Guide
Document Number: SC26-4045-05
http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/IGYA1101/3.3.2?SHELF=IGYSH007&DT=19930312141355
in section 3.3.2, Notice the last sentence of the second paragraph:
It is your responsibility to ensure that the contents of a data item
conform to its PICTURE and USAGE clauses before using
the data item in any further processing steps.
IBM has since toned down their previous statement for their latest compiler
but the intent remains the same:
Title: Enterprise Cobol for z/OS V3.4 Programming Guide
Document Number: SC27-1412-05
http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/IGY3PG30/1.3.7?SHELF=IGY3SH30&DT=20050628164603
in section 1.3.7, notice the last sentence of the first paragraph:
The compiler assumes that values you supply for a data item are valid
for the PICTURE and USAGE clauses, and does not check their validity.
Ensure that the contents of a data item conform to its PICTURE
and USAGE clauses before using the data item in any further
processing steps.
Also, notice the last sentence of the second paragraph:
When you give an item a value that is incompatible with its data
description, references to that item in the PROCEDURE DIVISION are
undefined and your results are unpredictable.
First, IBM is saying that all data must be valid before using it, but it is
contradictory because their default numeric processing compiler option is
NUMPROC(NOPFD), which means they will perform sign validation processing
trying to 'fix up' the user's data. This was done for compatibility with the
old IBM OS/VS Cobol compiler, but it doesn't always work.
Enterprise Cobol for z/OS V3.4 Programming Guide
http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/IGY3PG32/2.4.35?SHELF=IGY3SH33&DT=20061117131343
in section 2.4.35, notice the reference to using an INITIALIZE verb and
the comments about each of the NUMPROC options
In order to emulate IBM's default behavior Micro Focus uses this group of
directives:
NUMPROC(PFD) :
HOSTNUMMOVE HOSTNUMCOMPARE HOSTARITHMETIC
NOSIGNFIXUP CHECKNUM
NUMPROC(NOPFD):
HOSTNUMMOVE HOSTNUMCOMPARE HOSTARITHMETIC
SIGNFIXUP CHECKNUM
The first two are defaulted with a host dialect in Mainframe Express. The
others must be passed as Additional Directives.
Second, Micro Focus, on the other hand, believes that good code passes good
data. So we will stop a running program when the contents of a field are not
conforming to its PICTURE and USAGE definition. We have added many host
emulation directives to our compiler and made many runtime fixes in an
effort to emulate IBM's elusive behavior. We are close, but we will never
achieve exact compatibility because they do not document all their anomalies.
No one can guarantee when a S0C7 will happen on the host and when it will
not, so IBM has avoided such documentation.
Third, this case involves the use of uninitialized storage. IBM supplies a
runtime switch to initialize storage via their LE common runtime for Cobol,
C, Fortran, and PL/I. The switch is named STORAGE. It is described in the
LE Programming Reference.
Title: z/OS V1R9.0 Language Environment Programming Reference
Document Number: SA22-7562-09
http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/CEEA3180/CCONTENTS?SHELF=CEE2BK80&DN=SA22-7562-09&DT=20070428023816
in section 1.2.57 STORAGE:
http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/CEEA3180/1.2.57?SHELF=CEE2BK80&DT=20070428023816
But also reference 1.2.57.4 to read what IBM says about performance with
this option. The defaults in Micro Focus for INT code and GNT code use the
DEFAULTBYTE(00) directive to set uninitialized storage to binary Zeroes
(x'00'), but like IBM's option, this doesn't mean that the data is now
correct. The best answer is to use an IF NUMERIC test prior to any arithmetic
operations in your programs.
Fourth, IBM will accept invalid numeric data values such as Spaces or
Low-Values for Zoned Decimal data, because their generated code processes
data in four steps. First, the data item is packed. Second, the item has the
intended arithmetic operation performed. Third, the item is unpacked. And
finally the sign is 'fixed up' - that is to say, they will place a x'F' into
the high order 4 bits of the sign field if the field did not contain a
x'C' or x'D'.
Examples: x'0000' becomes x'F0F0' or a valid Zero
x'4040' becomes x'F0F0' or a valid Zero
x'40C5' becomes x'F0C5' or a valid 5
x'40D5' becomes x'F0D5' or a valid -5
Most customers are using as their default NUMPROC(NOPFD) for their host
compiles, so it is widely used by our customer base.
But, there is more. IBM has a new feature for acceptable valid signs:
Enterprise Cobol for z/OS V3.4 Programming Guide
http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/IGY3PG32/2.4.35?SHELF=IGY3SH33&DT=20061117131343
in section 2.4.35, notice the latest Enterprise Cobol for z\\OS V3R4
Programming Guide now documents that IBM accepts valid sign values 'A thru
F'. IBM has a history in this area. In the early 1980's OS/VS Cobol was
allowed for 18 months to use sign values of A-F. Then IBM decided it was
wrong and they pulled it from their code. However, because of a possible
user dependency created by this action, they had to supply a ZAP for those
customers who upgraded but relied on that particular behavior. VS Cobol II
had a ZAP to change the compiler to allow those sign values (IBM has since
dropped the CMPR2 compiler option). IBM APAR PL50260 states one must go to
the Program Directory, Page 44, and apply a usermod. This usermod was carried
from VS Cobol II into the LE Runtime library and has now been removed because
IBM is once again accepting A-F as valid signs. Here is the new text from the
link listed above:
| The compiler accepts any valid sign configuration: X'A', X'B', X'C', X'D',
| X'E', or X'F'. NUMPROC(NOPFD) is the recommended option in most cases.
Those vertical bars represent a change to the IBM manual. IBM says that A, C,
E, and F as positive. B and D are treated as negative. And take note that
section 1.3.6 of the same manual says F is both unsigned and positive:
http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/IGY3PG32/1.3.6?SHELF=IGY3SH33&DT=20061117131343#HDRWQ230
More references for initializing variables in the Cobol program:
Initializing variables VS Cobol II Programming Guide
section 3.4.5:
http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/IGYA1101/3.4.5?SHELF=IGYSH007&DT=19930312141355
Initializing variables Enterprise Cobol for z\\OS V3.4 Programming Guide
section 1.2.2 (a very nice table):
http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/IGY3PG30/1.2.2?SHELF=IGY3SH30&DT=20050628164603
When we wrote the Micro Focus Compiler and Runtime, we followed IBM's rules
as set forth in their manuals, but the values passed by IBM's code do not
always match their documentation in practice.
#MainframeExpressandMFE
#netexpress
#COBOL
#EnterpriseDeveloper
#ServerExpress
#MFDS
#Enterprise