View previous topic :: View next topic
|
Author |
Message |
Bill O'Boyle
CICS Moderator
Joined: 14 Jan 2008 Posts: 2501 Location: Atlanta, Georgia, USA
|
|
|
|
OK, I have a dumb question. I'm back doing applications and ran across a COBOL sub-program, with a PROCEDURE DIVISION USING, specifying several dozen parameters.
My question is this: Do the corresponding LINKAGE SECTION 01 levels need to be in the same order as specified in the USING?
FWIW, this is not an issue in Assembler and never has been.
Regards, |
|
Back to top |
|
|
don.leahy
Active Member
Joined: 06 Jul 2010 Posts: 765 Location: Whitby, ON, Canada
|
|
|
|
The order of the 01 levels in the LINKAGE section is unimportant.
By convention, they are usually coded in the same order, but it is is not necessary. |
|
Back to top |
|
|
Akatsukami
Global Moderator
Joined: 03 Oct 2009 Posts: 1788 Location: Bloomington, IL
|
|
|
|
I would say "Yes". The fine manual states:
Quote: |
The order of appearance of USING identifiers in both calling and called subprograms, or invoking methods or programs and invoked methods, determines the correspondence of single sets of data available to both. The correspondence is positional and not by name. For calling and called subprograms, corresponding identifiers must contain the same number of bytes although their data descriptions need not be the same. |
|
|
Back to top |
|
|
Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
|
|
|
|
Nope. Order is not relevant in the LINKAGE SECTION.
Many people think it is, and I've even had to entirely reverse the order of the LINKAGE SECTION definitions (and pocket a tenner) for one of these people.
Simple one-for-one from CALL ... USING ... to PROCEDURE DIVISION USING ...
Order in Linkage or Working-Storage or anywhere else is 100% irrelevant. |
|
Back to top |
|
|
Nic Clouston
Global Moderator
Joined: 10 May 2007 Posts: 2455 Location: Hampshire, UK
|
|
|
|
No. The declarations could be in Working-storage section if they have not been passed down from up on high. The only sequence that matters is on the CALL statement and, in the called program, on the PROCEDURE USING statement where they must be in sequence. |
|
Back to top |
|
|
Bill O'Boyle
CICS Moderator
Joined: 14 Jan 2008 Posts: 2501 Location: Atlanta, Georgia, USA
|
|
|
|
It makes sense to me that the order is irrelevant, although colleagues here insist the orders must match.
Because they call the shots and I'm just another larvae in the pool, I'll reluctantly comply.
Regards, |
|
Back to top |
|
|
Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
|
|
|
|
Don, it is not so much "by convention" as "by what people believe and are prepared to stick to as an article of faith until faced with a ridiculous level of proof and even then maybe not". In my experience.
Code: |
WORKING-STORAGE SECTION. (of Caller)
01 PROGA PIC X VALUE "Z".
01 PROGB PIC X VALUE "Y".
01 PROGC PIC X VALUE "Q".
CALL "VAR" USING PROGA, PROGB, PROGC
LINKAGE SECTION. (of Called)
01 PROGC PIC X.
01 PROGA PIC X.
01 PROGB PIC X.
PROCEDURE DIVISION USING PROGB, PROGC, PROGA. |
What is known as PROGA in the Caller becomes known as PROGB in the Called. B to C. C to A. They are not matched on name.
If the seventh item on the USING of the CALL is PRODMST-DELETE-FG and the seventh item on the USING of the PROCEDURE DIVISION is APPLE-PEACH-AND-PUMPKIN they are looking at the same storage, wherever and however defined.
This, from Akatsukami's manual quote, is a bald-faced lie (by the manual's contributors):
Quote: |
For calling and called subprograms, corresponding identifiers must contain the same number of bytes although their data descriptions need not be the same. |
Perhaps should normally would be OK. Can't be must as nothing enforces it. Must "if that's OK with you" cuts no M.... doesn't work.
* program names and data-names obfuscated for additional explicative purposes |
|
Back to top |
|
|
dick scherrer
Moderator Emeritus
Joined: 23 Nov 2006 Posts: 19244 Location: Inside the Matrix
|
|
|
|
Hello,
There may be confusion as to just What has to be in order.
The order of the fields in the USING statements needs to be in order.
It does not matter where the fields are in the WS or Linkage sections.
The call and the prodecure statements need the values in the same sequence.
Hopefully, i've not muddied the water . . . |
|
Back to top |
|
|
dbzTHEdinosauer
Global Moderator
Joined: 20 Oct 2006 Posts: 6966 Location: porcelain throne
|
|
|
|
Akatsukami's manual quote is correct with the following qualification.
if the CALLing linkage area is 10 bytes and the CALLed program defines it as 20,
and the CALLed program references any of the last 10 bytes,
it can cause a SOC4, but not always.
for example if the 10 bytes in the CALLing program are the last 10 bytes of the DATA DIV, then i would expect a SOC4.
there are compiler options (i forget which)
that can enforce the length of linkage areas in the CALLed program.
turn them off, and you can reference the first byte in the CALLing program,
pass the area as 1 byte to the CALLed program,
define the linkage as 1000 bytes in the CALLed,
and thus reference all the 1000 bytes in the CALLing program in the CALLed program.
if there are only 900 bytes in the CALLing program's DATA Div and you
reference any of the last 100 in the CALLed program,
you will have a SOC4, regardless of the compiler options. |
|
Back to top |
|
|
Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
|
|
|
|
Quote: |
For calling and called subprograms, corresponding identifiers must contain the same number of bytes although their data descriptions need not be the same. |
Code: |
WORKING-STORAGE SECTION.
01 LUMP PIC X.
CALL "A" USING LUMP
LINKAGE SECTION.
01 L-LUMP PIC X(100,000,000).
PROCEDURE DIVISION USING L-LUMP.
CALL "NEXTPRG" USING L-LUMP |
This is utterly, absolutely and 100% guaranteed OK in every single circumstance. It is not good practice, and gives no benefit in any way (and has a performance penalty) but it will compile and run in all circumstances.
TBC... |
|
Back to top |
|
|
Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
|
|
|
|
If a piece of data has had storage "obtained" for it (GETMAIN, or CEEGHST for instance) then exceeding the length of the storage acquired may well get a S0C4 (I don't know if it is possible to "abut" storage already "belonging"). The S0C4 occurs as soon as you access storage which does not "belong" to your run-unit.
With items from the WORKING-STORAGE of a COBOL program, things are the same, except that those items are part of a big chunk of storage which has been allocated and is "safe" to use (as in S0C4-free).
To demonstrate this, and estimate the extent of "safe" storage for cocked-up use, here's a program, compiled with NOSSRANGE, with a subscript deliberately running wild, looking byte-per-byte from the start of a storage area.
The storage area is either the first byte of the W-S of the program, or the byte "passed" from a CALLing program.
Code: |
ID DIVISION.
PROGRAM-ID. "WHATS0C4".
DATA DIVISION.
WORKING-STORAGE SECTION.
01 JUST-FOR-S0C4 PIC X.
01 BYTES-FROM-START-OF-STORAGE COMP-5 PIC 9(9).
01 ADDRESS-OF-2ND-LINKAGE USAGE POINTER.
01 FILLER
REDEFINES
ADDRESS-OF-2ND-LINKAGE.
05 FILLER COMP-5 PIC 9(9).
88 NO-LINKAGE VALUE ZERO.
01 W-WHEN-COMPILED PIC X(8)BX(8).
LINKAGE SECTION.
01 FIRST-BYTE-OF-SOME-DATA.
05 FILLER OCCURS 1.
10 A-BYTE PIC X.
01 L-BYTE PIC X.
88 EXPECTED-LINKAGE-VALUE VALUE "A".
01 L-DUMMY-FOR-OS PIC X.
PROCEDURE DIVISION USING
L-DUMMY-FOR-OS
L-BYTE
.
MOVE WHEN-COMPILED TO W-WHEN-COMPILED
DISPLAY "WHATS0C4 " W-WHEN-COMPILED
SET ADDRESS-OF-2ND-LINKAGE TO ADDRESS OF L-BYTE
IF NO-LINKAGE
SET ADDRESS OF FIRST-BYTE-OF-SOME-DATA
TO ADDRESS OF JUST-FOR-S0C4
DISPLAY "STAND-ALONE"
ELSE
SET ADDRESS OF FIRST-BYTE-OF-SOME-DATA
TO ADDRESS OF L-BYTE
IF EXPECTED-LINKAGE-VALUE
DISPLAY "CALLED"
ELSE
CALL "FRED"
END-IF
END-IF
PERFORM
VARYING BYTES-FROM-START-OF-STORAGE
FROM 1
BY 1
UNTIL BYTES-FROM-START-OF-STORAGE
GREATER THAN 999999999
MOVE A-BYTE ( BYTES-FROM-START-OF-STORAGE )
TO JUST-FOR-S0C4
DISPLAY BYTES-FROM-START-OF-STORAGE
END-PERFORM
GOBACK
. |
The program is either run as EXEC PGM=, or it is run as a CALLed program. For fun I CALLed it with two parameters, so it would use the data from the CALLing program, and with only one, mimicing the "CALL" from z/OS.
Code: |
EXEC PGM= fails after 0000048944
CALL with two items on USING fails afer 0000057136
CALL with one item on USING fails after 0000056944 |
It would seem that you can "safely" go some 48,000 bytes over the end of the storage which has been "passed" (no storage is passed, only addresses) and still not get a S0C4 if the data is in the WORKING-STORAGE of a COBOL program.
It would also seem that you get a slightly different amount of storage in different situations.
On the one hand this is of course bad. If something is that screwed up, it would be nice if it failed. On the other, the fact that COBOL in the language specification does not check for size (let alone type) of fields reduces the overhead. We test programs, so there are things we can live without the compiler giving us a helping hand on, if it avoids being processed billions of times once the program is in Prodcution.
So, check parameters. Check order on CALL ... USING matches order on PROCEDURE DIVISION USING. Check you have both USINGs. If there are any mismatches amongst any of that, the compiler will give no help at all through any sort of diagnostic message in any circumstance.
Going "10 bytes over" is not going to get a S0C4 for COBOL WORKING-STORAGE data "passed" through linkage. |
|
Back to top |
|
|
|