Recently we migrated our code from VS COBOL II to enterprise and we faced one problem.Below code abended in Enterprise COBOL -
MOVE SUB TO FETCH-CNT
01 SUB PIC 9(2) COMP
01 FETCH-CNT PIC 999
In NON LE the trunc coption was OPT.
In LE the trunc option is STD.
My hypothesis was the trunc option is playing the spoilsport, since in LE we are limiting the size of variable SUB to 2 bytes when 100 is moved only 00 is stored and hence the issue.
In NON LE the trunc option is OPT. Since 100 can still be stored in halfword, the truncation is not happening as a result the program is working.
To prove this, I put displays in both LE and NON LE modules. In LE the variable SUB shows 00 and then it is abending. In NON LE, the variable SUB shows 00, but FETCH-CNT shows 100 which means correct data is moved to FETCH-CNT. But my "Dsiplay" is limiting the display to 2 bytes ie 00 only. My question is -
1. Is my hypothesis correct? If so, how can I display that SUB is able to hold 100 in NON LE.
speak to the person/group that customized the new cobol installation
THEY should have read and understood before deploying it the differences between the old and new
and should know how to customize the new defaults option by assembling with the proper parameters the IGYCOPT macro
such a simple issue should have been spotted pretty early in the installation procedure
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
The options you are talking about are Cobol options, nothing to do with LE.
You only want OPT if your data conforms to PICture. Which means, if you have COMP PIC 9(2), then with OPT your results will be unreliable and only predictable from the particular code-sequence the compiler chooses to generate.
You should review all compile options, if one is "wrong" there may be others (plus note it is not "wrong", it is different).
Someone has not done there homework. Time to start it now.
EDIT: Meaning when you are stuffing greater than 99 into it.
Joined: 06 Jun 2008 Posts: 8696 Location: Dubuque, Iowa, USA
TRUNC(OPT) is a dangerous option, especially in production. From the Enterprise COBOL Programming Guide manual on the TRUNC option:
Quote:
Use the TRUNC(OPT) option only if you are sure that the data being moved into the binary areas will not have a value with larger precision than that defined by the PICTURE clause for the binary item. Otherwise, unpredictable results could occur. This truncation is performed in the most efficient manner possible; therefore, the results are dependent on the particular code sequence generated. It is not possible to predict the truncation without seeing the code sequence generated for a particular statement.
In other words, your site got lucky that OPT worked as BIN in your case -- it very easily could not have, and in my simple testing OPT worked like STD not BIN. Production sites should NEVER execute something where "unpredictable results could occur".
Testing your hypothesis is real simple -- compile a program that displays the values of SUB and FETCH-CNT after moving 100 to SUB, then moves SUB to FETCH-CNT. Use compiler option TRUNC(OPT) and execute, then recompile with TRUNC(BIN) and execute -- optionally, use TRUNC(STD) and recompile, then execute so you can see all the options.
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
How did you manage to get an "abend" with the line of code you showed? I can think of no possible way to get that line of code, with those data definitions, to abend, so I'm interested.
If your data "conforms to PICture" and is COMP or COMP-4 - ie, PIC 9 has max value of 9, PIC 99 has max of 99, PIC 999 has max of 999, PIC 9999, then you may reliably your TRUNC(OPT), TRUNC(STD), TRUNC(BIN) in Enterprise Cobol.
If your data does not "conform to PICture" - ie, you'd like to store 10 or more, 100 or more, 1,000 or more, 10,000 or more, then only TRUNC(BIN) or defining as COMP-5 will do what you want.
As Robert has indicated, using OPT in your original programs was not a good choice, as you either "got lucky" or you don't yet know how unlucky you got.
This, for me, is one of those "I wish it wasn't like that, but at least we've discovered it now, so let's check on what's gone wrong because of it" moments. If your system has been USING OPT and deliberately not conforming to PICture, then it's been an accident-waiting-to-happen,-or,-that-has-happened-and-is-waiting-to-be-noticed.
On the question of the DISPLAY, the only way you'll get it to show the full value in itself is by redefining it as a PIC XX and displaying that, then look at it in HEX. OPT is assuming, not unreasonably, that if your have PIC 99 then you only want two digits when you DISPLAY it.
The line of code i showed was the culprit and not exactly the line of code at which program abended. Basically the receiving field FIXED-CNT is used as a subscript, so when 100 was moved, the FIXED-CNT had 00, so when the data was inserted into the table..it abended with Array out of bound.
Anyways, thanks everyone for response, I will talk to the admin team on this now.
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
OK, that makes more sense. However, to move a binary field to a USAGE DISPLAY field to use it as a subscript... where it will get turned back into a binary (each time going via converting it to packed) is a little wasteful :-)
Joined: 14 Jan 2008 Posts: 2501 Location: Atlanta, Georgia, USA
Define the variable as an unsigned PIC 9(09) COMP or COMP-5 (if supported) and you won't go wrong.
Many years ago, out of the new fangled internal definition of the TRUNC compile option, I recommend programmers avoid halfwords and instead, use fullwords.
If you use TRUNC(OPT) and COMP-5 is not supported, your maximum is 999999999, which should cover you.
If your compiler supports COMP-5 (Native Binary), then use it instead.
The TRUNC option has no effect on COMP-5 variables and is ignored.
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
Yes, if you have a need to not conform to PICture, then use COMP-5 to define the item(s) in question.
You can then compile with either TRUNC(STD) or TRUNC(OPT) (OPT only if you are certain all other fields conform to PICture) without affecting the items defined as COMP-5.
If, however, it was just original coder-laziness to make something COMP PIC 99, then change it to 9(4)/9(9) (for TRUNC(STD)) or 9(4)/9(8) (for TRUNC(OPT)).
NOTE: TRUNC(OPT) behaves poorly with PIC 9(9). If you need that many digits and performance is a criteria use PIC 9(10)! This is according to R. J. Arellanes' Performance Tuning papers.
Joined: 14 Jan 2008 Posts: 2501 Location: Atlanta, Georgia, USA
Bill,
PIC 9(10) through PIC 9(18) COMP is treated as a Binary-Doubleword to COBOL (not that friendly to the language) and the last time I looked, COBOL uses run-time routines to perform arithmetic, which isn't that efficient. But, this was a while ago and the newer compilers may have changed and now do arithmetic in-line, especially if it's defined as COMP-5 and/or use 64-Bit register-instructions.
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
Bill,
The paper says it is only an issue for TRUNC(OPT). TRUNC(BIN) (and COMP-5) and don't make no nevermind about 9(9).
With TRUNC(OPT), 9(10) is faster to process than 9(9), apparently :-)
With OPT, the 9(10) through 9(17) are processed in doubleword format, but so is the 9(9), needing conversion from, and to, fullword, so slower. 9(18) goes to a higher precision than doubleword, apparently, so is slowest of all.
With TRUNC(STD) the 9(18) is also treated differently, as is the 9(9), slower than 1-8, but faster than 10-17.
With TRUNC(BIN) or COMP-5 the 9(18) remains as doubleword, it seems.
All big fun, and information tucked away.
Despite all the above, OPT is consistently faster overall, followed by STD, followed by BIN/COMP-5.
Of course, wait for all of the above to change with the new Compiler.
TRUNC(BIN) reflects the ANSI 85 standard. OPT and STD are IBM Extensions.