Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Is it possible to use the value of the PROGRAM ID within the source code?

115 views
Skip to first unread message

David Latimer

unread,
Jun 8, 2004, 6:31:31 AM6/8/04
to
I'm using MicroFocus COBOL 4.0 on UnixWare 2.1.3.

I'd quite like to be able to use the Program Id in every program using
the same phrase (e.g. MOVE prog id TO XYZ).

There are other ways of getting the same result but I just wondered if
this was possible.

David L.

Robert Wagner

unread,
Jun 9, 2004, 5:23:02 PM6/9/04
to
da...@quantumcat.demon.co.uk (David Latimer) wrote:

You cannot get it from Cobol but you can get it from Unix. Some Unixen store it
in an environment variable named _ (underscore). I know Solaris does. To read it
say:

01 program-name pic x(30) value spaces.
01 a-underscore pointer.
linkage section.
01 underscore pic x(30).

call 'cobgetenv' using z'_' returning a-underscore
set address of underscore to a-underscore
unstring underscore delimited by low-value into program-name

This only works if you compile to an executable, not .gnt.

The following will work on any species of Unix:

call 'system' using z"pgrep -s0 | xargs -Ipid ps -fppid | awk '{print $8}' | sed
-e'/CMD/d' -e'/xargs/d' -e'/ksh/d' -e'/awk/d' -e'/sed/d' >xxx"

Your program name will be in file xxx. Alternatively, you could send it to an
environment variable which can be read as above by changing >xxx to
| xargs -Iprog export _=prog

If you compile to .gnt, change awk to print $9. I used the -f option on ps so it
would show the whole command line.

Richard

unread,
Jun 10, 2004, 1:43:38 AM6/10/04
to
robert.d...@wagner.net (Robert Wagner) wrote

> >I'd quite like to be able to use the Program Id in every program using
> >the same phrase (e.g. MOVE prog id TO XYZ).

> If you compile to .gnt, change awk to print $9. I used the -f option on ps so it
> would show the whole command line.

That is not going to show the name of any CALLed programs, which is
probably the point of the request.

Robert Wagner

unread,
Jun 10, 2004, 2:44:13 AM6/10/04
to
rip...@Azonic.co.nz (Richard) wrote:

No, he wants the name of the Main program, probably to print in a log file or
report header. The logic getting the name would best be in a called program.
Printing 'getmyname' on every report would not be informative.

If programs are compiled to .gnt, the gnt _is_ a called program .. called by
cobrun, which would appear in column 8.

Stephen Gennard

unread,
Jun 10, 2004, 4:22:20 AM6/10/04
to
You could use x/open syntax...

01 ws-stuff pic x(80).

display 0 upon argument-number
accept ws-stuff from argument-value
display "Main exe is : " ws-stuff

It works with both "cobrun xx" and your program built as an exe....

--
Stephen

"David Latimer" <da...@quantumcat.demon.co.uk> wrote in message
news:a9026f4e.04060...@posting.google.com...

docd...@panix.com

unread,
Jun 10, 2004, 5:22:14 AM6/10/04
to
In article <40c800ce....@news.optonline.net>,

Robert Wagner <robert.d...@wagner.net> wrote:
>rip...@Azonic.co.nz (Richard) wrote:
>
>>robert.d...@wagner.net (Robert Wagner) wrote
>>
>>> >I'd quite like to be able to use the Program Id in every program using
>>> >the same phrase (e.g. MOVE prog id TO XYZ).
>>
>>> If you compile to .gnt, change awk to print $9. I used the -f option on ps so
>it
>>> would show the whole command line.
>>
>>That is not going to show the name of any CALLed programs, which is
>>probably the point of the request.
>
>No, he wants the name of the Main program, probably to print in a log file or
>report header.

Mr Wagner, how do you manage to translate 'I'd quite like... *every*
program using the same phrase' to 'he wants the name of the Main program'?

DD

Stephen Gennard

unread,
Jun 10, 2004, 5:47:25 AM6/10/04
to
If you had Server Express you could use CBL_GET_PROGRAM_INFO...

01 ws-pi-function pic x(4) comp-5.
01 ws-pi-param.
03 ws-pi-size pic x(4) comp-5.
03 ws-pi-flags pic x(4) comp-5.
03 ws-pi-handle usage pointer.
03 ws-pi-prog-id usage pointer.
03 ws-pi-gpi-attrs pic x(4) comp-5.
01 ws-pi-name-buf pic x(60).
01 ws-pi-name-len pic x(4) comp-5.


procedure division.

move 0 to ws-pi-function
move 20 to ws-pi-size
move 2 to ws-pi-flags
move length of ws-pi-name-buf to ws-pi-name-len
call "CBL_GET_PROGRAM_INFO" using
by value ws-pi-function
by reference ws-pi-param
by reference ws-pi-name-buf
by reference ws-pi-name-len
end-call

display "Return-code : " return-code
display ws-pi-name-buf

"David Latimer" <da...@quantumcat.demon.co.uk> wrote in message
news:a9026f4e.04060...@posting.google.com...

Donald Tees

unread,
Jun 10, 2004, 7:35:12 AM6/10/04
to
Stephen Gennard wrote:
> You could use x/open syntax...
>
> 01 ws-stuff pic x(80).
>
> display 0 upon argument-number
> accept ws-stuff from argument-value
> display "Main exe is : " ws-stuff
>
> It works with both "cobrun xx" and your program built as an exe....
>
> --

Normally, only one program of a run unit can be the EXE. You prbably
*KNOW* what is running at that point. It is after control transfers to
another program that you need the information.

Donald

Richard

unread,
Jun 10, 2004, 3:25:00 PM6/10/04
to
robert.d...@wagner.net (Robert Wagner) wrote

> >That is not going to show the name of any CALLed programs, which is
> >probably the point of the request.
>
> No, he wants the name of the Main program,

Where did you get that from ? What part of "every" did you not
understand ?

> probably to print in a log file or report header.

I do that, using the name of the program that prints the report, not
just the name of the 'main' program which is the same one in most of
my systems.

> The logic getting the name would best be in a called program.
> Printing 'getmyname' on every report would not be informative.

Then obviously, to me at least, this would _not_ be the 'best' if the
result would be completely useless. So why did you put 'best' ?

But he probably doesn't want 'mainprog' on every report either.



> If programs are compiled to .gnt, the gnt _is_ a called program .. called by
> cobrun, which would appear in column 8.

So, you have satisfied his 'every' with just 1 out of, potentially,
dozens of programs with different names.

The way that I get the program name available in each program in many
systems is to pass a parameter block around on each CALL that includes
the name used by the CALL. This, of course, is not a simple solution
for a system that doesn't do that.

The easiest way is probably to process all the source code to pick up
the word after Program-id (or use the file name) and add a W-S item
for all source files.

Robert Wagner

unread,
Jun 10, 2004, 6:45:00 PM6/10/04
to
docd...@panix.com wrote:


>Mr Wagner, how do you manage to translate 'I'd quite like... *every*
>program using the same phrase' to 'he wants the name of the Main program'?

Just a guess. Besides, there's no easy way to get the name of a called program.

Robert Wagner

unread,
Jun 10, 2004, 6:45:01 PM6/10/04
to
rip...@Azonic.co.nz (Richard) wrote:

>robert.d...@wagner.net (Robert Wagner) wrote
>
>> >That is not going to show the name of any CALLed programs, which is
>> >probably the point of the request.
>>
>> No, he wants the name of the Main program,
>
>Where did you get that from ? What part of "every" did you not
>understand ?
>
>> probably to print in a log file or report header.
>
>I do that, using the name of the program that prints the report, not
>just the name of the 'main' program which is the same one in most of
>my systems.

In the case of reports, I hardcode the program name in the header. If a program
prints two reports, I suffix the name with 1 and 2.

In the case of error messages from batch programs, we use a utility starter
program analogous to cobrun. It is an executable, the applications are
dynamically callable. The starter parses the command line, connects to the
database, does housekeeping such as setting nls_date_format, WRITES THE PROGRAM
NAME AND START TIME TO LOG FILES SYSOUT AND SYSERR, then calls the program.
Any messages from the program do not need a program id because it's already in
the log file.

The starter program could pass the program name as parameter 1, but we don't do
that. Structurally, the starter program *should* be the one to abort() if the
return code is non-zero. We can't do that because of a deficiency in 'anim',
which refuses to show called programs even though they are in the 'core' image.

>> The logic getting the name would best be in a called program.
>> Printing 'getmyname' on every report would not be informative.
>
>Then obviously, to me at least, this would _not_ be the 'best' if the
>result would be completely useless. So why did you put 'best' ?

I meant that if the called program getmyname got its own name, its output would
be uninformative. It should return the name of Main or Caller or, preferably, it
should walk back the whole call stack.

>The way that I get the program name available in each program in many
>systems is to pass a parameter block around on each CALL that includes
>the name used by the CALL. This, of course, is not a simple solution
>for a system that doesn't do that.

Our programs, developed on AS/400, keep an internal 'perform stack'. On entry to
every paragraph, they bump an index and insert the paragraph's name; on exit,
they set the index down by 1. A standard abend process in a copybook dumps the
'perform stack' to syserr. I was told by an AS/400 pro that the reason for this
is "The AS/400 debugger is so bad that programmers will do anything to avoid
using it." Out of curiosity, I looked at the debugger. It looks very much like
Micro Focus' anim. One can set breakpoints on lines of code, but not a data
elements, telling to stop when the element is touched or changed. Our most
common question is 'Show me when this field is changed to spaces'. Good
debuggers (possible oxymoron) such as MS DevStudio have it; bad ones don't.

[flame-bait alert] I don't use debuggers except as a last resort. They waste
more time than they save. If you can't read code and see what it does, you
shouldn't call yourself a programmer. Maybe you'd be happier as a tester. [end
of alert]

>The easiest way is probably to process all the source code to pick up
>the word after Program-id (or use the file name) and add a W-S item
>for all source files.

That's what he's gonna do, evinced by subsequent postings.

Chuck Stevens

unread,
Jun 10, 2004, 7:25:33 PM6/10/04
to

"Robert Wagner" <robert.d...@wagner.net> wrote in message
news:40c8d8c2....@news.optonline.net...

> Just a guess. Besides, there's no easy way to get the name of a called
program.

I wouldn't think this would be difficult for implementors to provide, and
would suggest you propose that a future standard provide an Intrinsic
Function to provide the program-name, function-name, class-name or
method-name of wherever you are at the moment. Whether it'd be
unconditionally meaningful or not is another question!

I'd also suggest that, if you called a program, the *caller* (so far as I
know always) knows its name, and if you need the called routine to know the
name by which it was called, I'd say passing the name using a by-value
parameter shouldn't take *that* many hours of head-scratching to figure out.
I mean, how difficult is CALL 'a-program' USING BY VALUE 'a-program' ... "?

-Chuck Stevens


docd...@panix.com

unread,
Jun 10, 2004, 7:29:18 PM6/10/04
to
In article <40c8d8c2....@news.optonline.net>,

Robert Wagner <robert.d...@wagner.net> wrote:
>docd...@panix.com wrote:
>
>
>>Mr Wagner, how do you manage to translate 'I'd quite like... *every*
>>program using the same phrase' to 'he wants the name of the Main program'?
>
>Just a guess.

I... see.

DD

Joe Zitzelberger

unread,
Jun 10, 2004, 9:44:11 PM6/10/04
to
Just a thought.

On z/OS you could find this information by looking at the PPA1 and PPA2
parts of the loaded program (offset 168 in one of those).

Whatever platform you are on must have a well defined object file format
(PEF, XCOFF, ELF, whatever). The docs for that format ought to tell you
how to find the executable name.

This method just begs for someone to reply with a "Cobol programmers
should never have to know load module format or use pointers or anything
that smells of programming..." post. But it really is easy to do...

William M. Klein

unread,
Jun 10, 2004, 9:52:47 PM6/10/04
to
Joe,
I won't reply the way you suggested, but rather by saying that *IF* one is in
an IBM mainframe environment, what this thread actually reminds me of is the
existing SHARE requriement,

"SSLNGC0313587 New LE Callable Service to get (various) Program Names
...
A new LE callable service (with capabilities well beyond CEE3GRN) should be
created to obtain various program names. This should include options to obtain:

- The currently executing program's name
- The name of the program that "activated" (Called, Invoked, whatever) the
currently executing program
- The name of the program at the "top" of the current LE "enclave"
- The name of the program at the "top" of the current LE "thread"

For each of these, sub-options may be required to provide information such as
- Any "alias" by which the program was entered
- Any "long-name" (with mixed characters) as supported by the Binder
- Any Entry-point name when other than the modules name

Finally, although not necessarily a part of this callable service, it would also
be desirable to be able to obtain the "data set name" (HFS, PDS, PDSE, LPA
member, or whatever) from which each of these entities was obtained."

--
Bill Klein
wmklein <at> ix.netcom.com
"Joe Zitzelberger" <joe_zitz...@nospam.com> wrote in message
news:joe_zitzelberger-BF...@corp.supernews.com...

Robert Wagner

unread,
Jun 11, 2004, 4:26:35 AM6/11/04
to
"Chuck Stevens" <charles...@unisys.com> wrote:

>
>"Robert Wagner" <robert.d...@wagner.net> wrote in message
>news:40c8d8c2....@news.optonline.net...
>
>> Just a guess. Besides, there's no easy way to get the name of a called
>program.
>
>I wouldn't think this would be difficult for implementors to provide, and
>would suggest you propose that a future standard provide an Intrinsic
>Function to provide the program-name, function-name, class-name or
>method-name of wherever you are at the moment. Whether it'd be
>unconditionally meaningful or not is another question!

A general-purpose solution would be to walk back the call stack returning the
names of all programs from the program of interest back to Main.

>I'd also suggest that, if you called a program, the *caller* (so far as I
>know always) knows its name,

Not necessarily. A certain breed likes to 'clone' programs by copying them to a
slightly different name, then changing a few lines of code. I've seen 15
'versions' of the same program.

> and if you need the called routine to know the
>name by which it was called, I'd say passing the name using a by-value
>parameter shouldn't take *that* many hours of head-scratching to figure out.
>I mean, how difficult is CALL 'a-program' USING BY VALUE 'a-program' ... "?

Generally, you can't pass strings on the stack. You can only pass words, such as
a pointer to the string. Make that 'CALL a-program USING (default BY REFERENCE)
a-program'.

Joe Zitzelberger

unread,
Jun 11, 2004, 8:21:54 AM6/11/04
to
In article <Pf8yc.9773$uX2....@newsread2.news.pas.earthlink.net>,

"William M. Klein" <wmk...@nospam.netcom.com> wrote:

> Joe,
> I won't reply the way you suggested, but rather by saying that *IF* one is
> in
> an IBM mainframe environment, what this thread actually reminds me of is the
> existing SHARE requriement,
>
> "SSLNGC0313587 New LE Callable Service to get (various) Program Names
> ...
> A new LE callable service (with capabilities well beyond CEE3GRN) should be
> created to obtain various program names. This should include options to
> obtain:
>
> - The currently executing program's name

This can be done via the prefix area.


> - The name of the program that "activated" (Called, Invoked, whatever) the
> currently executing program

The entire call chain can be observed using a tiny assembler program
that will dereference save areas and do a CSVQUERY on the owner of the
save area location.

> - The name of the program at the "top" of the current LE "enclave"

This can be done in Cobol by looking at the SWA.

> - The name of the program at the "top" of the current LE "thread"

I'm not sure how to do this one.

> For each of these, sub-options may be required to provide information such as
> - Any "alias" by which the program was entered
> - Any "long-name" (with mixed characters) as supported by the Binder
> - Any Entry-point name when other than the modules name
>
> Finally, although not necessarily a part of this callable service, it would
> also
> be desirable to be able to obtain the "data set name" (HFS, PDS, PDSE, LPA
> member, or whatever) from which each of these entities was obtained."

I'll post some code soon...

Chuck Stevens

unread,
Jun 11, 2004, 12:44:52 PM6/11/04
to

"Robert Wagner" <robert.d...@wagner.net> wrote in message
news:40c9685a....@news.optonline.net...

> A general-purpose solution would be to walk back the call stack returning
the
> names of all programs from the program of interest back to Main.

That is presuming that the implementation has an accessible structure such
as a "call stack".

> Not necessarily. A certain breed likes to 'clone' programs by copying them
to a
> slightly different name, then changing a few lines of code. I've seen 15
> 'versions' of the same program.

Yes, you could have any number of programs with the same PROGRAM-ID, even in
the same multiple-program structure. If these programs are all
separately-compiled, the PROGRAM-ID becomes less interesting as seen from
outside the program, and what is important is how the calling program refers
to the separately-compiled called program.

> Generally, you can't pass strings on the stack. You can only pass words,
such as
> a pointer to the string. Make that 'CALL a-program USING (default BY
REFERENCE)
> a-program'.

Last sentence first: "CALL a-program USING BY CONTENT a-program" would I
think be preferable. The objective here is to ensure that a-program cannot
step on this particular parameter.

In our implementation, there is no pre-execution-time linking phase; the
determination as to whether the target procedure is nested or
separately-compiled has to be made at execution time and is a rather
expensive process. Thus, while "CALL <dataname>" works it is almost
invariably much more costly than "CALL <literal>".

And I was indeed mistaken; I was looking at the wrong format in ISO/IEC
1989:2002. By-value and by-content literal parameters are only allowed in
program-prototype calls.

But where does the standard require that the implementor keep track of
information about calling history in some sort of hardware stack? Where
does the standard prohibit putting strings (do you mean strictly
"alphanumeric literals" or do you include "alphanumeric data items"?) on
that stack?

BY CONTENT non-numeric parameters of arbitrary length are allowed.

How the implementation *accomplishes* passing, say, a 30,000-byte record as
a parameter BY CONTENT is none of the end user's business; the only concern
is how the caller sees it if the called program happens to step on its
contents (and the correct expectation is that it be unchanged).

So far as I know there's nothing wrong with
MOVE "a-program" TO program-to-call.
CALL "a-program" USING BY CONTENT program-to-call ...
or even
MOVE "a-program" TO program-to-call.
CALL program-to-call USING BY CONTENT program-to-call ...
if one is so inclined.

What's this about words? It may be *common* to use some sort of fixed
structure to describe a parameter passed by content -- but there is
absolutely no requirement that that structure be inherently different from
the structure that would be used for parameters passed by reference, or that
the structure be related in any way to any other structure that might be
used in the operating environment.

Moreover, there is nothing except resources and incentive preventing an
obsolete-computer buff from implementing a fully-2002-compliant COBOL
implementation on a Burroughs B3500, or even an IBM 1401, for which
architectures the concept of "fixed-length words" as I understand the
concept does not exist.

-Chuck Stevens


Richard

unread,
Jun 11, 2004, 8:04:27 PM6/11/04
to
robert.d...@wagner.net (Robert Wagner) wrote

> A general-purpose solution would be to walk back the call stack returning the
> names of all programs from the program of interest back to Main.

That doesn't solve anything. It is unlikely that the name of the
calling program, nor even that of the called program is actually on
the stack (presuming that it soes actually do this using a stack in
the first place). When a program does a 'CALL progname USING
parameters', you will notice that progname is _not_ one of the
parameters.

But also the CALL does not necessarily go to the called program
directly. It most likely goes to the run-time resolver, so going one
up the stack does not necessarily go to the caller.

So even if one could work out the stack frames to access the calling
program there is still _nothing_ as a 'general-purpose' in that
program that would give that name. If there was then it would also be
in the called program, so walking the stack is unrequired.

> >I'd also suggest that, if you called a program, the *caller* (so far as I
> >know always) knows its name,

> Not necessarily. A certain breed likes to 'clone' programs by copying them to a
> slightly different name, then changing a few lines of code. I've seen 15
> 'versions' of the same program.

I am not sure why you think that this means that the caller does not
know its own name ? Are you saying that the programmer copies the
code to a new file and does not change the program-id, or other
references ?

This can become a problem with, say, Microfocus, where a dynamic
loading for a CALL is by file name and a CANCEL is by Program-Id. If
they don't match there can be unrequired results.

Robert Wagner

unread,
Jun 11, 2004, 8:14:13 PM6/11/04
to
"Chuck Stevens" <charles...@unisys.com> wrote:

>"Robert Wagner" <robert.d...@wagner.net> wrote in message
>news:40c9685a....@news.optonline.net...
>
>> A general-purpose solution would be to walk back the call stack returning
>the
>> names of all programs from the program of interest back to Main.
>
>That is presuming that the implementation has an accessible structure such
>as a "call stack".

Every called program has a way of returning to its caller.

>> Generally, you can't pass strings on the stack. You can only pass words,
>such as
>> a pointer to the string. Make that 'CALL a-program USING (default BY
>REFERENCE)
>> a-program'.
>
>Last sentence first: "CALL a-program USING BY CONTENT a-program" would I
>think be preferable. The objective here is to ensure that a-program cannot
>step on this particular parameter.

But it can. It just cannot modify it back in the caller's memory.

I don't think this is a realistic concern. Programs generally don't recklessly
modify parameters.

>In our implementation, there is no pre-execution-time linking phase; the
>determination as to whether the target procedure is nested or
>separately-compiled has to be made at execution time and is a rather
>expensive process. Thus, while "CALL <dataname>" works it is almost
>invariably much more costly than "CALL <literal>".

It is in nearly all environments. It need not be. Sure, dataname can change, but
99.99 percent of the time it doesn't. INLINE code could (should) check that it's
the same and then call directly, with little more overhead than a static link. I
used to write enhancers that reached back and modified generated code to do
exactly that.

> where does the standard require that the implementor keep track of
>information about calling history in some sort of hardware stack? Where
>does the standard prohibit putting strings (do you mean strictly
>"alphanumeric literals" or do you include "alphanumeric data items"?) on
>that stack?
>
>BY CONTENT non-numeric parameters of arbitrary length are allowed.
>
>How the implementation *accomplishes* passing, say, a 30,000-byte record as
>a parameter BY CONTENT is none of the end user's business; the only concern
>is how the caller sees it if the called program happens to step on its
>contents (and the correct expectation is that it be unchanged).

True but discordant with the culture of operating systems and other languages.
Micro Focus says:

"If the program being called is not COBOL, the size of the additional data item
should not exceed the maximum size of the system area (typically the size of a
POINTER on the system); otherwise the system might become catastrophically
corrupt."

You wouldn't want to be the one found to have "catastrophically corrupted" the
system. I know .. FUD.

>What's this about words? It may be *common* to use some sort of fixed
>structure to describe a parameter passed by content -- but there is
>absolutely no requirement that that structure be inherently different from
>the structure that would be used for parameters passed by reference, or that
>the structure be related in any way to any other structure that might be
>used in the operating environment.

The idea of BY CONTENT and BY VALUE is based on paranoia and disrespect. Its
premise is that called programs may irrationally corrupt parameter values. In
the real world, that's not a realistic concern.

>Moreover, there is nothing except resources and incentive preventing an
>obsolete-computer buff from implementing a fully-2002-compliant COBOL
>implementation on a Burroughs B3500, or even an IBM 1401, for which
>architectures the concept of "fixed-length words" as I understand the
>concept does not exist.

On the 1401 I wrote a rudimentary operating system because the machine didn't
come with one. On the B3500/4700 I completely rewrite the communications
software and print spooler in Cobol and contributed to the design of MCPV.

You're correct: they didn't have words nor stacks, but they did have a pointer
back to the caller.

Robert Wagner

unread,
Jun 12, 2004, 11:25:40 AM6/12/04
to
rip...@Azonic.co.nz (Richard) wrote:

>robert.d...@wagner.net (Robert Wagner) wrote
>
>> A general-purpose solution would be to walk back the call stack returning the
>> names of all programs from the program of interest back to Main.
>
>That doesn't solve anything. It is unlikely that the name of the
>calling program, nor even that of the called program is actually on
>the stack (presuming that it soes actually do this using a stack in
>the first place). When a program does a 'CALL progname USING
>parameters', you will notice that progname is _not_ one of the
>parameters.

The stack contains a return address. Using that, the program name can usually be
found near the beginning of its segment or in a public symbol table.

>But also the CALL does not necessarily go to the called program
>directly. It most likely goes to the run-time resolver, so going one
>up the stack does not necessarily go to the caller.

Let's try to stay in focus. We're interested in the RETURN address, not the call
address.

>So even if one could work out the stack frames to access the calling
>program there is still _nothing_ as a 'general-purpose' in that
>program that would give that name. If there was then it would also be
>in the called program, so walking the stack is unrequired.

Heap walkers are a very common diagnostic tool. I'm disappointed to read you're
unfamiliar with the concept.

>> >I'd also suggest that, if you called a program, the *caller* (so far as I
>> >know always) knows its name,
>

>> A certain breed likes to 'clone' programs by copying them to a
>> slightly different name, then changing a few lines of code. I've seen 15
>> 'versions' of the same program.
>
>I am not sure why you think that this means that the caller does not
>know its own name ? Are you saying that the programmer copies the
>code to a new file and does not change the program-id, or other
>references ?

Yes, it is common practice. Then I'm asked to 'find every place where a program
does A and change it to B.' I find 15 copies of the same program doing A. Nobody
knows which is the production version. The files' 'last touched' timestamps are
all the same, the last time someone ran a GREP.

Thinking ahead, I'd developed a tool to track program executions. It shows one
of the 15 running every day, the others seldom or never. I change that one.
Months later the file gets broken. Hours of research leads to 'we run that
program when someone asks for special handling.' Why didn't you put special
handling logic in the production program? The answer: 'I believe in the KISS
principle.'

This kind of abuse is WHY big shops are burdened with Change Management software
and programmers locked out of the production box.

>This can become a problem with, say, Microfocus, where a dynamic
>loading for a CALL is by file name and a CANCEL is by Program-Id. If
>they don't match there can be unrequired results.

Cancel? Let the operating system worry about cleanup.

Richard

unread,
Jun 12, 2004, 6:10:03 PM6/12/04
to
robert.d...@wagner.net (Robert Wagner) wrote

> The stack contains a return address. Using that, the program name can usually

The 'return address' need not be to the actual CALLing program. It
may be to the run-time so that the run-time can decrement the 'active'
counter or somesuch. The run-time does know which programs are
active, which is why it can give an error when a re-entry is tried.

> found near the beginning of its segment or in a public symbol table.

I just looked as some object code. Yes the program name is there, so
are a lot of other names, and in no particular order. This is also
_not_ a general solution as you claimed and may be entirely specific
to particualr compilers and environments, each one requiring a
different solution.



> >But also the CALL does not necessarily go to the called program
> >directly. It most likely goes to the run-time resolver, so going one
> >up the stack does not necessarily go to the caller.
>
> Let's try to stay in focus. We're interested in the RETURN address, not the
> call address.

And the return address may be back to the run-time which is where the
actual entry to the called program came from.

> >So even if one could work out the stack frames to access the calling
> >program there is still _nothing_ as a 'general-purpose' in that
> >program that would give that name. If there was then it would also be
> >in the called program, so walking the stack is unrequired.
>
> Heap walkers are a very common diagnostic tool. I'm disappointed to read
> you're unfamiliar with the concept.

You are now confused between the stack and the heap. They are
different things you know.

As I said there is still _nothing_ that make this a general solution.

> Yes, it is common practice. ...

> Thinking ahead, I'd developed a tool to track program executions. It shows one
> of the 15 running every day, the others seldom or never. I change that one.

So, how did you know which one ran ? Obviously not from the
Program-Id if they were all the same.

How did the program get executed ? Something must have specified its
name, presumably its file name. Surely you should have been able to
find which one was run by looking at what CALLed it, or the job cards.

> Months later the file gets broken. Hours of research leads to 'we run that
> program when someone asks for special handling.'

That shows you have a complete lack of 'thinking ahead'. Either you
should have changed all 15 or should have 'archived' the other 14 so
they could be used.

> Yes, it is common practice. ...

> This kind of abuse is WHY big shops are burdened with Change Management
> software and programmers locked out of the production box.

The 'common practice' and 'burdened by CMS' seem to be incompatible.

Richard

unread,
Jun 12, 2004, 6:13:03 PM6/12/04
to
robert.d...@wagner.net (Robert Wagner) wrote

> >That is presuming that the implementation has an accessible structure such
> >as a "call stack".
>
> Every called program has a way of returning to its caller.

But that not not imply that the called program has _access_ to the
caller's memory nor to anything above that.

JerryMouse

unread,
Jun 12, 2004, 6:41:41 PM6/12/04
to

Inasmuch as this thread has wandered over all creation, let's start another:

Why do you want to do this? What do you want to accomplish?

In olden days, programmers used to mark the start of Working-Storage with:

01 FILLER PIC X(24) VALUE 'START OF WORKING-STORAGE.

We use the same technique. All our COBOL programs start with:

01 FILLER PIC X(24) VALUE 'Microsoft C++ (c) 1997'.


LX-i

unread,
Jun 12, 2004, 7:21:00 PM6/12/04
to
JerryMouse wrote:
>
> In olden days, programmers used to mark the start of Working-Storage with:
>
> 01 FILLER PIC X(24) VALUE 'START OF WORKING-STORAGE.

Wow! In olden days, you used to be able to omit the closing quote? ;)


--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~ / \ / ~ Live from Montgomery, AL! ~
~ / \/ o ~ ~
~ / /\ - | ~ LXi...@Netscape.net ~
~ _____ / \ | ~ http://www.knology.net/~mopsmom/daniel ~
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
~ I do not read e-mail at the above address ~
~ Please see website if you wish to contact me privately ~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Clark F. Morris, Jr.

unread,
Jun 12, 2004, 7:39:25 PM6/12/04
to
Chuck Stevens wrote:

>> much snipped


>
> Moreover, there is nothing except resources and incentive preventing an
> obsolete-computer buff from implementing a fully-2002-compliant COBOL
> implementation on a Burroughs B3500, or even an IBM 1401, for which
> architectures the concept of "fixed-length words" as I understand the
> concept does not exist.

I remember the 1401. It had characters with six bits plus a word mark
bit. All fields were terminated by a word mark, a record mark or a
group mark. I forget whether the group mark was a record mark with the
word mark bit set or a record mark was a group mark with the word mark
bit set. The 1401/1440 definitely could not handle the 2002 standard
with only three character addresses maximum and I doubt the big brothers
1410/7010 would have been equal to the task. With all fields being
variable, the series was not well suited to COBOL with multiple record
formats. Many of the instructions were variable length of 1, 4 or 7
characters. The Move Instruction M meant Move A to B stopping at the
word mark. If an address was omitted it meant pick up where the
previous instruction left off. All told an intriguing machine.
Emulation on Intel would be interesting. It probably would be slow.
>
> -Chuck Stevens
>
>


Robert Wagner

unread,
Jun 12, 2004, 10:10:30 PM6/12/04
to
rip...@Azonic.co.nz (Richard) wrote:

>robert.d...@wagner.net (Robert Wagner) wrote
>
>> The stack contains a return address. Using that, the program name can usually

>
>The 'return address' need not be to the actual CALLing program. It
>may be to the run-time so that the run-time can decrement the 'active'
>counter or somesuch. The run-time does know which programs are
>active, which is why it can give an error when a re-entry is tried.

Even if the program does return to a run-time, the return address will be below
it on a stack. It has to be in order for recursion to work.

>> found near the beginning of its segment or in a public symbol table.
>
>I just looked as some object code. Yes the program name is there, so
>are a lot of other names, and in no particular order. This is also
>_not_ a general solution as you claimed and may be entirely specific
>to particualr compilers and environments, each one requiring a
>different solution.

The location of the name is defined by the file format, which is defined by the
operating system. It has to be so Task Viewers can show what's running,
including called programs.

>> >So even if one could work out the stack frames to access the calling
>> >program there is still _nothing_ as a 'general-purpose' in that
>> >program that would give that name. If there was then it would also be
>> >in the called program, so walking the stack is unrequired.
>>
>> Heap walkers are a very common diagnostic tool. I'm disappointed to read
>> you're unfamiliar with the concept.
>
>You are now confused between the stack and the heap. They are
>different things you know.

Heap walkers and Task viewers follow the same concept, and are often integrated.
The concept is walking up and down a tree structure.

>> Thinking ahead, I'd developed a tool to track program executions. It shows
one
>> of the 15 running every day, the others seldom or never. I change that one.
>
>So, how did you know which one ran ? Obviously not from the
>Program-Id if they were all the same.

From the file name. Logging executions is especially easy when they use 'cobrun'
to start programs. Write a script named 'cobrun' and put it ahead of Micro Focus
in the PATH.

>How did the program get executed ? Something must have specified its
>name, presumably its file name. Surely you should have been able to
>find which one was run by looking at what CALLed it, or the job cards.

That just moves the problem up a level without solving it. There may be obsolete
scripts running obsolete programs. Some programs were run by a human typing the
name on a command line. Some are called by dead code hooked to a menu item that
no longer displays.

Analysis of the thousands of programs showed the same happening at the file
level. There were thousands of FDs that were never opened, or opened but not
read or written, or opened for update but not updated. I posted the analysis
program here last year.

This is what happens when programs are 'written' by copy-and-paste.

>> Months later the file gets broken. Hours of research leads to 'we run that
>> program when someone asks for special handling.'
>
>That shows you have a complete lack of 'thinking ahead'. Either you
>should have changed all 15 or should have 'archived' the other 14 so
>they could be used.

If I changed all 15, the forces of darkness would say I was wasting time
changing obsolete programs. If I'd archived the unused ones, they'd wait for (or
create) a crisis, then point the finger at me for removing an 'essential'
program. Or they'd run it unmodified, thereby breaking the file.

What SHOULD have been done was complete elimination of duplicate code. OO makes
it easier to do that. If one needs 'special handling' for one run, he or she
overloads a method for that run only.

>> This kind of abuse is WHY big shops are burdened with Change Management
>> software and programmers locked out of the production box.
>
>The 'common practice' and 'burdened by CMS' seem to be incompatible.

Undisciplined redundant code is found in small shops lacking Change Management.
Big shops make a clear distinction between production code and everything else.
Obfuscators still find ways to ply their trade. ODBC is one of their best
friends, enabling them to write applications in Access without the inconvenience
of controls. Access feels like a programming environment designed by Walmart.
The more things change, the more they stay the same.

Robert Wagner

unread,
Jun 12, 2004, 10:12:17 PM6/12/04
to
rip...@Azonic.co.nz (Richard) wrote:

The language requires this to work:

Program A: call 'B' using BY REFERENCE a-1
Program B: call 'C' using BY REFERENCE a-1, b-2
Program C: display 'I have access to ' a-1 ' and ' b-2

Operating systems protect memory at the Process level. Can you cite one that
works at the called program level? I thought not.


Richard

unread,
Jun 13, 2004, 2:09:53 AM6/13/04
to
robert.d...@wagner.net (Robert Wagner) wrote

> >But that not not imply that the called program has _access_ to the
> >caller's memory nor to anything above that.
>
> The language requires this to work:
>
> Program A: call 'B' using BY REFERENCE a-1
> Program B: call 'C' using BY REFERENCE a-1, b-2
> Program C: display 'I have access to ' a-1 ' and ' b-2
>
> Operating systems protect memory at the Process level. Can you cite one that
> works at the called program level? I thought not.

It doesn't need to be protected by the OS to not have access to
something, just because you have a return address to the code segemnt
(presuming it is not just the run-time's) does not mean that you can
usefully find the data segement.

The LINKAGE areas may be of little use as these, as you show, may be
areas in some other program entirely.

Richard

unread,
Jun 13, 2004, 2:17:35 AM6/13/04
to
robert.d...@wagner.net (Robert Wagner) wrote

> Even if the program does return to a run-time, the return address will be below
> it on a stack. It has to be in order for recursion to work.

It may be _somewhere_ on the stack. Of course if it is .int code then
it isn't a real return address but an address in the byte code that
the interpreter will use.

> The location of the name is defined by the file format, which is defined by the
> operating system. It has to be so Task Viewers can show what's running,
> including called programs.

What is in memory is entirely what the run-time wants it to be. For
example .int and .gnt aren't loaded as executables. The 'task' is the
run-time byte interpreter.

> Heap walkers and Task viewers follow the same concept, and are often
> integrated.
> The concept is walking up and down a tree structure.

What stack is a 'tree structure' ?

Robert Wagner

unread,
Jun 13, 2004, 6:19:12 AM6/13/04
to
rip...@Azonic.co.nz (Richard) wrote:

>robert.d...@wagner.net (Robert Wagner) wrote

>What is in memory is entirely what the run-time wants it to be. For


>example .int and .gnt aren't loaded as executables. The 'task' is the
>run-time byte interpreter.

Micro Focus says those formats are retained only for backward compatibility.
They recommend OS standard formats: executable, .so and .dll.

>> Heap walkers and Task viewers follow the same concept, and are often
>> integrated.
>> The concept is walking up and down a tree structure.
>
>What stack is a 'tree structure' ?

The calling and called programs form a tree structure.

JerryMouse

unread,
Jun 13, 2004, 8:08:43 AM6/13/04
to
LX-i wrote:
> JerryMouse wrote:
>>
>> In olden days, programmers used to mark the start of Working-Storage
>> with:
>>
>> 01 FILLER PIC X(24) VALUE 'START OF WORKING-STORAGE.
>
> Wow! In olden days, you used to be able to omit the closing quote?
> ;)

No, there's a continuation line. Remember those?


Paul Raulersonv

unread,
Jun 13, 2004, 11:52:59 AM6/13/04
to
Isn't this getting a little bit out of hand?

Some compilers use entry logic that stores the program name in the stack frame for
just this purpose.

On some platforms you can compile with debugging enabled, which will set STABS
information in the link-edited file, accomplishing the same thing

Most shops that really want to do this define standard entry-logic for their programs
which includes a step to store the program name in WS or some other well known space.

On the mainframe, you have ADATA records that can help you out.

-Paul

"Richard" <rip...@Azonic.co.nz> wrote in message news:217e491a.04061...@posting.google.com...

Richard

unread,
Jun 13, 2004, 3:12:59 PM6/13/04
to
robert.d...@wagner.net (Robert Wagner) wrote

> >What stack is a 'tree structure' ?


>
> The calling and called programs form a tree structure.

No they don't, the structure of 'the stack' is 'a stack', like a stack
of plates it grows and shrinks along a single axis.

A 'tree structure', like an actual tree, has branches. A binary tree,
for example, has left and right pointers.

Sometimes I don't know whether you are just confused of whether you
are trolling.

LX-i

unread,
Jun 13, 2004, 3:13:44 PM6/13/04
to

Heh - remember? I've used 'em - used one last week. :)

Robert Wagner

unread,
Jun 13, 2004, 8:11:30 PM6/13/04
to
rip...@Azonic.co.nz (Richard) wrote:

>Sometimes I don't know whether you are just confused of whether you
>are trolling.

I'm not trolling. You don't understand the points I try to make.

Clark F. Morris, Jr.

unread,
Jun 13, 2004, 8:42:14 PM6/13/04
to
The problem with using PROGRAM-ID is that it has no necessary
operational significance in many environments. On the IBM OS360 and
successor operating systems (z/OS being the latest incarnation), a
program could have a source member name of X123 and be compiled and
linked to give an executable name of X123 while the PROGRAM-ID value is
Z456. While this is bad policy, the operating system will happily
execute X123 or accept dynamic CALLs of X123, executing them correctly
and won't recognize Z456.

Joe Zitzelberger

unread,
Jun 14, 2004, 9:00:59 AM6/14/04
to
In article <40cbb7c3....@news.optonline.net>,
robert.d...@wagner.net (Robert Wagner) wrote:

MVS, OS/390, z/OS.

While it does not protect memory at the program level. It does limit
switches to supervisor state (e.g. free access to all system memory) at
the program level.

Thus, a process with its own protected memory can call an 'authorized'
program, which can then read any memory in the system regardless of
protection level or owner.

Tom Morrison

unread,
Jun 14, 2004, 9:11:56 AM6/14/04
to
"Clark F. Morris, Jr." <cfm...@istar.ca> wrote in message
news:cag4bh$j8c$1...@news.eusc.inter.net...
[snip]

> Emulation on Intel would be interesting. It probably would be slow.

It all depends on what your definition of 'slow' is.

My first computer programming job (outside of college) was translating 1401
Autocoder to this new-fangled 360 COBOL. This was done for a large
manufacturing concern that literally had acres (hectares) of 360s, including
row upon row of 360/30s running in 1401 emulation mode. Of course they
were faster than the 1401s they replaced.

There is absolutely no doubt in my mind that the 2.8GHz Intel waiting for me
to type this could emulate several 1401s between keystrokes, and still
perform better than the original 1401 speed!

Tom Morrison


Robert Wagner

unread,
Jun 14, 2004, 12:01:23 PM6/14/04
to
Joe Zitzelberger <joe_zitz...@nospam.com> wrote:

>In article <40cbb7c3....@news.optonline.net>,
> robert.d...@wagner.net (Robert Wagner) wrote:
>
>> rip...@Azonic.co.nz (Richard) wrote:
>>
>> >robert.d...@wagner.net (Robert Wagner) wrote
>> >
>> >> >That is presuming that the implementation has an accessible structure
such
>> >> >as a "call stack".
>> >>
>> >> Every called program has a way of returning to its caller.
>> >
>> >But that not not imply that the called program has _access_ to the
>> >caller's memory nor to anything above that.
>>
>> The language requires this to work:
>>
>> Program A: call 'B' using BY REFERENCE a-1
>> Program B: call 'C' using BY REFERENCE a-1, b-2
>> Program C: display 'I have access to ' a-1 ' and ' b-2
>>
>> Operating systems protect memory at the Process level. Can you cite one that
>> works at the called program level? I thought not.
>
>MVS, OS/390, z/OS.
>
>While it does not protect memory at the program level. It does limit
>switches to supervisor state (e.g. free access to all system memory) at
>the program level.

Every operating system does that. The issue was limiting access within a
Process.

>Thus, a process with its own protected memory can call an 'authorized'
>program, which can then read any memory in the system regardless of
>protection level or owner.

Sounds like a hole in security. Another process might have cleartext of an
encrypted document.

Chuck Stevens

unread,
Jun 14, 2004, 12:06:36 PM6/14/04
to

"Clark F. Morris, Jr." <cfm...@istar.ca> wrote in message
news:cag4bh$j8c$1...@news.eusc.inter.net...

> I remember the 1401. It had characters with six bits plus a word mark


> bit. All fields were terminated by a word mark, a record mark or a
> group mark. I forget whether the group mark was a record mark with the
> word mark bit set or a record mark was a group mark with the word mark
> bit set. The 1401/1440 definitely could not handle the 2002 standard
> with only three character addresses maximum and I doubt the big brothers
> 1410/7010 would have been equal to the task. With all fields being
> variable, the series was not well suited to COBOL with multiple record
> formats. Many of the instructions were variable length of 1, 4 or 7
> characters. The Move Instruction M meant Move A to B stopping at the
> word mark. If an address was omitted it meant pick up where the
> previous instruction left off. All told an intriguing machine.

I maintain that *given enough time* you could do anything on a 1401. It
might not be easy. It might not be straightforward. But presuming the task
at hand did not require peripherals unavailable on a 1401 it is *doable* if
you're willing to wait long enough.

I remember writing a model of the chemical reactions in the human retina
(which involved five simultaneous linear differential equations with
coefficients too great to allow for Runge-Kutta techniques, requiring a
Laplace transform which had to be solved for the quartic and thence to the
binomials using Newton-Raphson iterations) on, first, an Interdata Model 3
(which had no hardware multiply/divide, much less floating-point hardware),
and subsequently on a Wang 700 programmable calculator using code
segmentation and automatic loading on the program cassette drive.

While the Wang took a few hours to do a "run", and the Interdata took three
days, two hours, and ten minutes, the same equation could be solved in a few
minutes on the Philco 2000/210.

I didn't say the 1401 would execute 2002 COBOL code *rapidly*

> Emulation on the Intel would be interesting. It probably would be slow.

Actually, I doubt it!

-Chuck Stevens


Chuck Stevens

unread,
Jun 14, 2004, 12:22:15 PM6/14/04
to

"Robert Wagner" <robert.d...@wagner.net> wrote in message
news:40cb1626...@news.optonline.net...

>
> The stack contains a return address. Using that, the program name can
usually be
> found near the beginning of its segment or in a public symbol table.

Define "usually". Definitely *not* the case for Unisys MCP systems; the
only place the name of the called program appears at execution time is in
the execution-time library template for external programs and not at all for
unambiguously nested ones (for which the name is resolved at compile time)!

> Let's try to stay in focus. We're interested in the RETURN address, not
the call
> address.

What does a PCW have to do with a name?

> Heap walkers are a very common diagnostic tool. I'm disappointed to read
you're
> unfamiliar with the concept.

I'm familiar enough with the concept; it escapes me why you feel walking a
heap (or a stack, for that matter) is universally applicable to standard
COBOL in all, or even most, implementations.

-Chuck Stevens


Chuck Stevens

unread,
Jun 14, 2004, 12:29:29 PM6/14/04
to
"Robert Wagner" <robert.d...@wagner.net> wrote in message
news:40cce67e....@news.optonline.net...

The job of communicating to an audience lies to significant degree with the
person trying to make the points. That you are not succeeding with Richard
(or, for that matter, frequently with me) is not necessarily his, or my,
fault.

Often I do understand the points you make. You've indicated that a user
program can access its own stack at execution time, or alternatively that a
user-written program can access another program's stack. On machines where
the hardware design prohibits such access as a security measure, your
assertion is ... ummm ... unlikely.

-Chuck Stevens


Chuck Stevens

unread,
Jun 14, 2004, 1:46:46 PM6/14/04
to

"Robert Wagner" <robert.d...@wagner.net> wrote in message
news:40ca30db...@news.optonline.net...

> Every called program has a way of returning to its caller.

That does not mean that mechanism is necessarily visible to the caller, the
called program, or to an outside process.

> > The objective here is to ensure that a-program cannot
> > step on this particular parameter.

> But it can. It just cannot modify it back in the caller's memory.

True; that's precisely the point of the difference between BY CONTENT and BY
REFERENCE. A called program *can* step on the parameter in the caller's
memory if it's BY REFERENCE.

> I don't think this is a realistic concern. Programs generally don't
recklessly
> modify parameters.

It was a realistic enough problem in a Fortran environment I worked on back
in about 1970, in which the constant integer 1 was passed to a subroutine
that modified its value. And it was a realistic enough problem during the
development of the '85 standard to stimulate the framers of that standard
into adding "by content" to the parameter descriptions in CALL and "by
value" to the Procedure Division header. Programs may not generally
*recklessly* modify parameters, but it is not uncommon for them
*inadvertently* to do so!


> It is in nearly all environments. It need not be. Sure, dataname can
change, but
> 99.99 percent of the time it doesn't. INLINE code could (should) check
that it's
> the same and then call directly, with little more overhead than a static
link. I
> used to write enhancers that reached back and modified generated code to
do
> exactly that.

In our environment, if you use CALL <dataname> it is precisely because you
expect the contents of <dataname> to change from one execution to the next.


> > where does the standard require that the implementor keep track of
> >information about calling history in some sort of hardware stack? Where
> >does the standard prohibit putting strings (do you mean strictly
> >"alphanumeric literals" or do you include "alphanumeric data items"?) on
> >that stack?
> >
> >BY CONTENT non-numeric parameters of arbitrary length are allowed.
> >
> >How the implementation *accomplishes* passing, say, a 30,000-byte record
as
> >a parameter BY CONTENT is none of the end user's business; the only
concern
> >is how the caller sees it if the called program happens to step on its
> >contents (and the correct expectation is that it be unchanged).
>
> True but discordant with the culture of operating systems and other
languages.

I'm not sure what you're responding to here. I have been actively
supporting compilers for four dialects of ALGOL, two of Pascal, three of
COBOL, and miscellaneous other language compilers *and* their operating
environments for quite some time now, and I don't see the discordance you
assert.

> Micro Focus says:
>
> "If the program being called is not COBOL, the size of the additional data
item
> should not exceed the maximum size of the system area (typically the size
of a
> POINTER on the system); otherwise the system might become catastrophically
> corrupt."

Unlikely on our system because of memory protection hardware. A fatal
termination of the offending program would almost certainly result. Can be
done, but you have to go *way* out of your way (like, call an ALGOL
subprogram that changes the size of a data item) to do it, and the manual
already says it's the user's responsibility to ensure that parameter. The
standard already says that the parameter in a Procedure Division USING
phrase must be the same size *or smaller* than in the program that calls it
if the caller passes it by reference, so that means the called program can't
get outside the bounds of what it's passed. Wouldn't the same thing
reasonably apply when what's being called isn't in COBOL? Aren't the
consequences of violating the rules of the standard undefined? What's your
point?

> The idea of BY CONTENT and BY VALUE is based on paranoia and disrespect.
Its
> premise is that called programs may irrationally corrupt parameter values.
In
> the real world, that's not a realistic concern.

No, it is based on the premise of *safeguarding* parameter values. It is
not merely "irrational" corruption that it guards against, it is also
"inadvertent" corruption as well as "malevolent" corruption. A called
routine can protect itself and its data from a malevolent caller, and a
calling program can protect itself and its data from a
malevolently-substituted called routine. And, however silly you might find
the idea, it's been part of COBOL for nigh onto twenty years now, and it
ain't going anywhere soon!

> You're correct: they didn't have words nor stacks, but they did have a
pointer
> back to the caller.

Didn't say they didn't. What I did say was that it wasn't a *word*, nor did
it necessarily bear any relationship to any other hardware or software
structure in the system.

-Chuck Stevens


Chuck Stevens

unread,
Jun 14, 2004, 2:11:28 PM6/14/04
to

"Robert Wagner" <robert.d...@wagner.net> wrote in message
news:40cbb7c3....@news.optonline.net...

> The language requires this to work:
>
> Program A: call 'B' using BY REFERENCE a-1
> Program B: call 'C' using BY REFERENCE a-1, b-2
> Program C: display 'I have access to ' a-1 ' and ' b-2

True enough. It also requires that if you change a-1 that change is visible
in Program A, and if you change b-2, that change is visible in Program B.

The language also requires that if Program A contains data items a-3 and
a-4, and Program B has data items b-3 and b-4, B cannot "see" a-1 or a-2
(unless, of course, they're declared global and B is nested in A), nor can C
see b-3 or b-4 (unless they're global and C is nested in B) or a3 or a-4
(unless they're global and C is nested within B which is nested within A).

Moreover, given

Program A: call 'B' using BY CONTENT a-1
Program B: call 'C' using BY CONTENT a-1, b-2
Program C: display 'I have access to ' a-1 ' and ' b-2 '
will execute, but any changes B or C make to a-1 or b-2 will *not* be
visible in their "owning" programs.

> Operating systems protect memory at the Process level. Can you cite one
that
> works at the called program level?

Depends on what you mean by "memory", "protect", and "process", to say
nothing of the blanket "operating systems". Protection of the "local"
memory of a called program is a function of the operating environment as it
relates to the characteristics of the *program*. It's not so much the
"operating system" as it is the "hardware" in our case, but the operating
system does participate. Parameters are protected, or not protected, as
specified by the authors of both the called and calling programs. If the
memory is shared between them (by reference in the calling and called
programs), then it's shared; if it's any other combination (by reference in
the calling program, by value in the called or vice versa, or by value in
both), the rules require that the formal and actual parameters be "treated
as if" they were separate memory areas.

In the case of Unisys MCP, it's the *compiler* that handles these
distinctions, not the operating system. So, yes, I can cite one that works
at the called program level rather than at the operating system level.

> I thought not.

I'm afraid you thought wrong.

-Chuck Stevens


Kindrick Ownby

unread,
Jun 14, 2004, 3:29:49 PM6/14/04
to
Chuck Stevens wrote:
[...]

> I maintain that *given enough time* you could do anything on a 1401. It
> might not be easy. It might not be straightforward. But presuming the task
> at hand did not require peripherals unavailable on a 1401 it is *doable* if
> you're willing to wait long enough.
[...]


My 1401 story is more mundane - the company had payroll
running on a 16K 1401 with multiply/divide, and wanted
to downgrade to a 4K 1401 without multiply/divide. They
did retain tape, on which I developed macros for the
multiply/divide, and on which I could store intermediate
results. The resulting program had two phases, with the
data cards inserted between the two portions of the program.


Kindrick

Robert Wagner

unread,
Jun 14, 2004, 8:31:51 PM6/14/04
to
"Chuck Stevens" <charles...@unisys.com> wrote:

>"Robert Wagner" <robert.d...@wagner.net> wrote in message
>news:40ca30db...@news.optonline.net...

>> I don't think this is a realistic concern. Programs generally don't


>recklessly
>> modify parameters.
>
>It was a realistic enough problem in a Fortran environment I worked on back
>in about 1970, in which the constant integer 1 was passed to a subroutine
>that modified its value. And it was a realistic enough problem during the
>development of the '85 standard to stimulate the framers of that standard
>into adding "by content" to the parameter descriptions in CALL and "by
>value" to the Procedure Division header. Programs may not generally
>*recklessly* modify parameters, but it is not uncommon for them
>*inadvertently* to do so!

In 40+ years Cobol programming, I've never used BY CONTENT (unless the called
program required it).

>> It is in nearly all environments. It need not be. Sure, dataname can
>change, but
>> 99.99 percent of the time it doesn't. INLINE code could (should) check
>that it's
>> the same and then call directly, with little more overhead than a static
>link. I
>> used to write enhancers that reached back and modified generated code to
>do
>> exactly that.
>
>In our environment, if you use CALL <dataname> it is precisely because you
>expect the contents of <dataname> to change from one execution to the next.

I dispute that. You use it because you want to force dynamic links and the
compiler doesn't provide a suitable option such as DYNAM, which makes all calls
dynamic.

In the Unix world, late binding is the default.

>> True but discordant with the culture of operating systems and other
>languages.
>
>I'm not sure what you're responding to here. I have been actively
>supporting compilers for four dialects of ALGOL, two of Pascal, three of
>COBOL, and miscellaneous other language compilers *and* their operating
>environments for quite some time now, and I don't see the discordance you
>assert.

Other languages discourage or outright prohibit passing large structures on the
stack. That's the provenance of malloc (intra-process) or Shared Memory (across
processes). The caller is expected to allocate a chunk and pass a pointer to it.


Robert Wagner

unread,
Jun 14, 2004, 8:31:52 PM6/14/04
to
"Chuck Stevens" <charles...@unisys.com> wrote:

>Often I do understand the points you make. You've indicated that a user
>program can access its own stack at execution time, or alternatively that a
>user-written program can access another program's stack. On machines where
>the hardware design prohibits such access as a security measure, your
>assertion is ... ummm ... unlikely.

If a program couldn't access its own stack, it wouldn't be able to return from a
call.

If it couldn't access the caller's stack, this wouldn't work:

Program A: call 'B' using by content a1
Program B: display "A's stack is at " address of a1

Robert Wagner

unread,
Jun 14, 2004, 8:31:54 PM6/14/04
to
"Chuck Stevens" <charles...@unisys.com> wrote:

>"Robert Wagner" <robert.d...@wagner.net> wrote in message
>news:40cb1626...@news.optonline.net...
>
>>
>> The stack contains a return address. Using that, the program name can
>usually be
>> found near the beginning of its segment or in a public symbol table.
>
>Define "usually". Definitely *not* the case for Unisys MCP systems; the
>only place the name of the called program appears at execution time is in
>the execution-time library template for external programs and not at all for
>unambiguously nested ones (for which the name is resolved at compile time)!

When a runtime error occurs and the program isn't handling it, doesn't Cobol
issue a message containing the program name and a description of the error?

Isn't there a debug compiler option, which preserves names?

>> Heap walkers are a very common diagnostic tool. I'm disappointed to read
>you're
>> unfamiliar with the concept.
>
>I'm familiar enough with the concept; it escapes me why you feel walking a
>heap (or a stack, for that matter) is universally applicable to standard
>COBOL in all, or even most, implementations.

Near the beginning of this thread, we discussed identifying programs in error
messages. I opined that the error reporting mechanism should walk back the stack
reporting the names of all programs leading to one of interest.

Robert Wagner

unread,
Jun 14, 2004, 8:31:55 PM6/14/04
to
"Chuck Stevens" <charles...@unisys.com> wrote:

>"Clark F. Morris, Jr." <cfm...@istar.ca> wrote in message
>news:cag4bh$j8c$1...@news.eusc.inter.net...
>

>I maintain that *given enough time* you could do anything on a 1401. It
>might not be easy. It might not be straightforward. But presuming the task
>at hand did not require peripherals unavailable on a 1401 it is *doable* if
>you're willing to wait long enough.

I maintain a machine needs only one instruction to solve any problem. There
wouldn't be an opcode. The four operands would be o1 and o2, the source and
destination for a (possibly indexed) copy; o3, the object of a test; and o4, the
address and condition of a call.

Let's call this hypothetical machine CADET, for Can't Add, Doesn't Even Try. It
could do arithmetic by table lookup using two indicies. The RCA 301 actually
worked that way. If someone stepped on the arithmetic table at a fixed address
in low memory, answers came out wrong until you rebooted the machine.

>I remember writing a model of the chemical reactions in the human retina
>(which involved five simultaneous linear differential equations with
>coefficients too great to allow for Runge-Kutta techniques,

Adams-Moulton techniques would likely have handled the range.

>requiring a
>Laplace transform which had to be solved for the quartic and thence to the
>binomials using Newton-Raphson iterations)

Birge-Vieta methods of pivotal condensation would have speeded up that phase.

Robert Wagner

unread,
Jun 14, 2004, 8:31:50 PM6/14/04
to
"Chuck Stevens" <charles...@unisys.com> wrote:

>
>"Robert Wagner" <robert.d...@wagner.net> wrote in message
>news:40cbb7c3....@news.optonline.net...

>> Operating systems protect memory at the Process level. Can you cite one


>that
>> works at the called program level?
>
>Depends on what you mean by "memory", "protect", and "process", to say
>nothing of the blanket "operating systems". Protection of the "local"
>memory of a called program is a function of the operating environment as it
>relates to the characteristics of the *program*. It's not so much the
>"operating system" as it is the "hardware" in our case, but the operating
>system does participate.

Every platform I've worked on also uses hardware. But the operating system tells
the hardware about zones of memory and ids of authorized users. Typically, the
zones are "segments" and the user is a "process id". Thus, every called program
has access to the memory of all other programs within the process .. as far as
the hardware is concerned.

Does Unisys MCP setup user ids smaller than a 'process'?

>Parameters are protected, or not protected, as
>specified by the authors of both the called and calling programs. If the
>memory is shared between them (by reference in the calling and called
>programs), then it's shared; if it's any other combination (by reference in
>the calling program, by value in the called or vice versa, or by value in
>both), the rules require that the formal and actual parameters be "treated
>as if" they were separate memory areas.
>
>In the case of Unisys MCP, it's the *compiler* that handles these
>distinctions, not the operating system. So, yes, I can cite one that works
>at the called program level rather than at the operating system level.

Would Unisys MCP or compiler stop this:

Program A:
01 bunch-of-pointers.
05 pointer-to-a4 pointer.
05 pointer-to-a5 pointer.

set pointer-to-a4 to address of a4
set pointer-to-a5 to address of a5
call 'B' using bunch-of-pointers

Program B:
linkage section.
01 bunch-of-pointers.
05 pointer-to-a4 pointer.
05 pointer-to-a5 pointer.
01 a4 pic x.
01 a5 pic x.
procedure division using bunch-of-pointers.
set address of a4 to pointer-to-a4
set address of a5 to pointer-to-a5
display 'I can see ' a4 ' and ' a5

Jim Morcombe

unread,
Jun 15, 2004, 12:40:49 AM6/15/04
to
Obviously it depends on just what you want to do wit hthe Program Name and
why.

I use this type of thing to identify the actual program being run. But I am
not interested in just the name of the program, but the version as well.

The PROGRAM-ID doesn't give you the version so it is useless for my
purposes.

Instead, I define a Working Storage variable (with the inovative name of
PROG-NAME) and I use CVS commands to define the value. This means that when
some idiot copies the program and doesn't change "PROGRAM-ID", I still pick
up the real name of the program. It also gives me the version number as
well.

I would imagine that most systems have some kind of Source Code Control
System capable of doing this.

Jim Morcombe

Robert Wagner <robert.d...@wagner.net> wrote in message

news:40c800ce....@news.optonline.net...


> rip...@Azonic.co.nz (Richard) wrote:
>
> >robert.d...@wagner.net (Robert Wagner) wrote
> >

> >> >I'd quite like to be able to use the Program Id in every program using
> >> >the same phrase (e.g. MOVE prog id TO XYZ).
> >
> >> If you compile to .gnt, change awk to print $9. I used the -f option on
ps so
> it
> >> would show the whole command line.
> >
> >That is not going to show the name of any CALLed programs, which is
> >probably the point of the request.
>
> No, he wants the name of the Main program, probably to print in a log file
or
> report header. The logic getting the name would best be in a called
program.
> Printing 'getmyname' on every report would not be informative.
>
> If programs are compiled to .gnt, the gnt _is_ a called program .. called
by
> cobrun, which would appear in column 8.
>


Richard

unread,
Jun 15, 2004, 3:22:52 AM6/15/04
to
robert.d...@wagner.net (Robert Wagner) wrote

> In 40+ years Cobol programming, I've never used BY CONTENT (unless the called
> program required it).

How would a CALLed program specify that it _requires_ a parameter to
be passed BY CONTENT ?

> >In our environment, if you use CALL <dataname> it is precisely because you
> >expect the contents of <dataname> to change from one execution to the next.
>
> I dispute that. You use it because you want to force dynamic links and the
> compiler doesn't provide a suitable option such as DYNAM, which makes all
> calls dynamic.

Why do you assume that in his environment he does not have a way to
make calls using literals as being dynamic ? On some COBOL systems
_all_ CALLs are dynamic, even when using literals.

Disputing and contradicting people about environments you seem to know
little about may sometimes be the sign of trolling.

> In the Unix world, late binding is the default.

Which may be irrelevant to what any particualr COBOL system does. For
example using .int does not need to use what the 'Unix world' uses.

Joe Zitzelberger

unread,
Jun 15, 2004, 7:58:06 AM6/15/04
to
There is an emulator that claims the 1401. The SIMH runs on Intel and
windows:

http://simh.trailing-edge.com/

So the theory of a fast 1401 can be tested...

Chuck Stevens

unread,
Jun 15, 2004, 12:26:22 PM6/15/04
to

"Robert Wagner" <robert.d...@wagner.net> wrote in message
news:40ce1792....@news.optonline.net...

> Every platform I've worked on also uses hardware. But the operating system
tells
> the hardware about zones of memory and ids of authorized users.

In the case of Unisys MCP, programs request memory during their initiation.
The descriptors pointing to that memory are contained within the program's
stack, and the only processes that can see those descriptors, or the memory
they point to, are the programs themselves and the MCP. Even the
descriptors are indirect, as they reference a MCP table that contain the
*actual* descriptors of the code segments. The only authorized user of a
space of memory is the process that created it, unless that process
explicitly provides a path to it (for example, as a parameter to a task or
library).

> Typically, the
> zones are "segments" and the user is a "process id". Thus, every called
program
> has access to the memory of all other programs within the process .. as
far as
> the hardware is concerned.

Nope. Not even close.

> Does Unisys MCP setup user ids smaller than a 'process'?

"User id's" arent germane to Unisys MCP memory management, as I see it. You
want memory? You build a descriptor template; first time you touch that
template, the MCP allocates the memory. The descriptor to that memory is in
*your* stack; nobody else but the MCP can see it, or the memory it
addresses, unless you pass them the descriptor. You go away? The MCP
deallocates the memory as part of the process of tearing the stack down.

> Would Unisys MCP or compiler stop this:
>
> Program A:
> 01 bunch-of-pointers.
> 05 pointer-to-a4 pointer.

> ...

Umm... Yeah, sure would, at "pointer-to-A4 pointer". I think you're
laboring under at least one mistaken assumption here.

The Unisys MCP environment currently supports two dialects of COBOL:
COBOL74, which follows ANSI X3.23-1974, and COBOL85, which follows ANSI
X3.23-1985 plus the two amendments.

USAGE POINTER was introduced in ISO/IEC 1989:2002 and is an *extension* to
any implementation of COBOL that conforms to any *prior* standard.

Thus, Unisys MCP software does not recognize the above code as meaningful
simply because USAGE POINTER isn't in either ANSI X3.23-1974 or ANSI
X3.23-1985, nor is it implemented as a Unisys extension to either of those
standards in either of the Unisys MCP COBOL compilers.

Unisys might consider adding USAGE POINTER to the list of 2002-standard
features for consideration for inclusion in our ANSI-85 compiler, but before
we could do so we would need at least one Unisys MCP user to let it be known
to us that they found it a desirable enhancement, and we have not as yet
been notified of such a request. The enhancements that people have actually
asked for have to take precedence (for example, INITIALIZE WITH FILLER has
been requested as a means of improving performance of INITIALIZE).

The current memory management scheme, and the security it affords our users,
is a well-liked feature of the Unisys MCP environment that our users have
liked since our introduction of it in the Burroughs B5000 and through its
refinement over a number of generations of hardware design. It is not clear
to us that providing a mechanism whereby users could pretty much arbitrarily
get to any memory of any component of a run unit without the most local
"owner" of that memory having any say in the matter would represent an
improvement in either security or functionality to our existing customers.

-Chuck Stevens


Chuck Stevens

unread,
Jun 15, 2004, 12:31:17 PM6/15/04
to
"Robert Wagner" <robert.d...@wagner.net> wrote in message
news:40ce1f14....@news.optonline.net...

> If a program couldn't access its own stack, it wouldn't be able to return
from a
> call.

Silly me. I was under the impression that the EXIT (or RETN) hardware
operators, with a RCW on the stack placed there by the caller and invisible
to the called routine, handled that. Must've been wrong all these years.

> If it couldn't access the caller's stack, this wouldn't work:
>
> Program A: call 'B' using by content a1
> Program B: display "A's stack is at " address of a1

Could you point out to me once again where "address of" appears in ANSI
X3.23-1985 (or, for that matter ANSI X3.23-1974)?

-Chuck Stevens


Chuck Stevens

unread,
Jun 15, 2004, 12:38:34 PM6/15/04
to

"Robert Wagner" <robert.d...@wagner.net> wrote in message
news:40ce2169....@news.optonline.net...

> When a runtime error occurs and the program isn't handling it, doesn't
Cobol
> issue a message containing the program name and a description of the
error?

The outermost object code file name is reflected in the basic error message.
The stack history is reflected by sequence number in the log; the program
dump provides more details for separately-compiled programs.

> Isn't there a debug compiler option, which preserves names?

What's to preserve?

> Near the beginning of this thread, we discussed identifying programs in
error
> messages. I opined that the error reporting mechanism should walk back the
stack
> reporting the names of all programs leading to one of interest.

No, perhaps *you* discussed identifying programs in error messages; I don't
recall having participated in that part of the discussion.

In our case, because the fundamental architecture of the system is
stack-based to begin with, identifying the history from the point of failure
all the way through all the nested calls is handled. Names are available
for separately-compiled programs, but COBOL programs in the Unisys MCP
environment typically have unique sequence numbers for each source line, a
nested program forms part of a compilation unit, and the sequence numbers
(together, sometimes, with the code address in the RCW) provides enough
information for the user to figure out the calling sequence that led to the
failure. The program-id of a nested program may show up, but that's not
what people used to working with Unisys MCP COBOL85 use as a primary
debugging tool.

-Chuck Stevens


Chuck Stevens

unread,
Jun 15, 2004, 12:45:13 PM6/15/04
to

"Jim Morcombe" <j...@byronics.com.au> wrote in message
news:caltrm$ft9$1...@yeppa.connect.com.au...

> The PROGRAM-ID doesn't give you the version so it is useless for my
> purposes.
>
> Instead, I define a Working Storage variable (with the inovative name of
> PROG-NAME) and I use CVS commands to define the value. This means that
when
> some idiot copies the program and doesn't change "PROGRAM-ID", I still
pick
> up the real name of the program. It also gives me the version number as
> well.

Note that the Intrinsic Function amendment (ANSI X3.23a-1989) included
WHEN-COMPILED alongside CURRENT-DATE, both of which provide their respective
information in the same format. This doesn't speak to a source-code
version number as such, but this function should help provide *some* sort of
unique identification for the compiled object code.

-Chuck Stevens


Richard

unread,
Jun 15, 2004, 3:01:12 PM6/15/04
to
robert.d...@wagner.net (Robert Wagner) wrote

> Would Unisys MCP or compiler stop this:

> [...]


> set pointer-to-a4 to address of a4
> set pointer-to-a5 to address of a5
> call 'B' using bunch-of-pointers

> [...]


> display 'I can see ' a4 ' and ' a5

You seem to assume that just because you can see some parts of the
memory of the calling program as passed by parameters in a stack frame
that therefore you would be able to access every other part of that
program.

In some cases the Working-Storage of a program is not all one
contiguous segement. The compiler cannot split 01 levels or 77 levels
(actually it could as long as the result was logically identical), but
there is no reason to assume that any or all 01s or 77s are in the
same segment or have an address that is determinable from the address
of another, or from a code address such as the return in the stack.

In fact you may not even be able to determine the address of the stack
frame of the calling program, there is no guarantee that the run-time
has not created a new stack to pass parameters and return address to
the program while keeping the caller's stack private.

Chuck Stevens

unread,
Jun 15, 2004, 3:13:53 PM6/15/04
to

"Robert Wagner" <robert.d...@wagner.net> wrote in message
news:40ce3a88....@news.optonline.net...

> In 40+ years Cobol programming, I've never used BY CONTENT (unless the
called
> program required it).

Using standard COBOL you couldn't do so until the introduction of the syntax
in the '85 standard, less than twenty years ago. I never used Function
CURRENT-DATE in COBOL68, either, but I'm not sure that says anything about
whether anyone might find it useful or efficacious!

Certainly I've used the equivalents in ALGOL and Pascal many a time, and the
absence of CONTENT / VALUE from ANSI X3.23-1974 was a restriction that
"bilingual" (ALGOL/COBOL) programmers found decidedly limiting.

> >In our environment, if you use CALL <dataname> it is precisely because
you
> >expect the contents of <dataname> to change from one execution to the
next.

> I dispute that. You use it because you want to force dynamic links and the
> compiler doesn't provide a suitable option such as DYNAM, which makes all
calls
> dynamic.

If I understand your definition of "dynamic links", under the Unisys MCP
implementation of COBOL IPC to separately-compiled programs, *all* such
CALLs *are* dynamic. Some implementations resolve such things using a
"linkage editor", as I understand it; the Unisys MCP analog to this is a
product called "BINDER". For standard COBOL programs, the compilers produce
*executable code*, directly, period. There is no "post-compilation" step
other than execution in such a case; BINDER is not involved in ANSI IPC
calls. At all. Ever.

I would guess that *both* CALL <literal> *and* CALL <dataname> generate
"dynamic calls" in this environment by your definition. While it's true
that the first such CALL is more costly than a call to, say, a
separately-compiled procedure (which requires non-standard syntax and a
post-compilation step), once the MCP has initiated the called program and
established the linkage, the performance is essentially the same, because
the object code's essentially the same.

What's different about CALL <literal> and CALL <dataname>? In CALL
<literal> the library template is constructed at compilation time. In CALL
<dataname> the library template must be constructed as part of the object
code associated with the CALL itself, and destroyed immediately upon return
from the procedure. That means an InitialPBIT for the library template on
each CALL and a BLOCKEXIT call to the MCP on each return. That's expensive.

On Unisys MCP systems, if you want to be able to call a separately-compiled
procedure that has somehow been incorporated into your COBOL object program,
you don't do it using ANSI IPC calls, you do it through Unisys extensions
associated with calling procedures that have been incorporated using BINDER.
This syntax is somewhat similar to the IPC syntax, but not identical. That
appears to me to be the sense of what I think you'd refer to as a "static
link" -- a link established after compilation but before execution. You can
do it on our system, but it's not part of the ANSI IPC implementation.

> In the Unix world, late binding is the default.

In the Unisys MCP world as it relates to ANSI IPC to separately-compiled
programs, binding occurs on first CALL, period. There is no "early" or
"late" in the ANSI IPC context, there is only the linkage established by the
MCP at execution time. If you want "early" binding, then don't use ANSI IPC
syntax, use declaratives with USE EXTERNAL, bind the procedure in, and use
CALL <section-name>.

> Other languages discourage or outright prohibit passing large structures
on the
> stack. That's the provenance of malloc (intra-process) or Shared Memory
(across
> processes). The caller is expected to allocate a chunk and pass a pointer
to it.

What other languages -- from ALTAC to C# -- do or did and how and why they
did it is not necessarily germane to the design and history of, or
requirements for, COBOL. Pascal allows all sorts of stuff that neither
Fortran66 nor RPG allow, and prohibits stuff that even COBOL(68) thought was
the bee's knees. What's your point?

If your expectation is that all implementations "allocate a chunk and pass a
pointer to it", all I can say is the advice some wise friends gave me: "an
expectation is a premeditated resentment". The code generated for the call
may be expected *by you* to look the way you want it to and to make the data
available to the called routine in a particular fashion, but that's your
expectation, to which you are welcome, and that expectation does not
necessarily have anything to do with general reality.

Even if the implementor does decide to pass some sort of description of the
data, rather than the data itself, to the called program, there's no
guarantee that that description would bear any relationship or similarity to
what might pass for a "USAGE POINTER" data item in that implementor's
implementation (real, planned, or hypothetical) of ISO/IEC 1989:2002 COBOL,
or anything else, for that matter.

The decision as to what the code to pass a parameter BY CONTENT actually
*does* is up to the implementor; the standard offers guidelines as to what
the *overall effect* of that code should be.

-Chuck Stevens


Chuck Stevens

unread,
Jun 15, 2004, 3:37:36 PM6/15/04
to

"Richard" <rip...@Azonic.co.nz> wrote in message
news:217e491a.04061...@posting.google.com...

> You seem to assume that just because you can see some parts of the
> memory of the calling program as passed by parameters in a stack frame
> that therefore you would be able to access every other part of that
> program.

That is certainly not the case in Unisys MCP COBOLs.

> In some cases the Working-Storage of a program is not all one
> contiguous segement. The compiler cannot split 01 levels or 77 levels
> (actually it could as long as the result was logically identical), but
> there is no reason to assume that any or all 01s or 77s are in the
> same segment or have an address that is determinable from the address
> of another, or from a code address such as the return in the stack.

Most definitely.

In Unisys MCP COBOL74, *each* 01-level item and *each* 77-level item has a
separate structure in memory, each allocated when it is first "touched" by
the program. And although COBOL74 doesn't split 01-level items into
separate blocks of memory, COBOL(68) allowed the user to do so. In COBOL74
there is no possibility of accessing beyond the bounds of an 01-level item;
the *hardware* prohibits it, whether the access is as a source or a
destination.

In Unisys MCP COBOL85, to cut down on the stack cell requirements, data is
"pooled", so it is at least theoretically possible to get outside one's
"own" 01-level item within a program; otherwise, those "pools" are again
local to the program. I can also demonstrate that 01-level items used as
parameters are allocated their own locations, whether passed by value or by
reference, so the same rule applies as is true for COBOL74: just because
you can get to an 01-level record (for access or for update) from the called
program does not mean you can get to the one declared before or after it, or
any other record not passed as a parameter, in the calling program. The
COBOL compiler *and* the hardware conspire to prevent such access from
anyone but the MCP.

-Chuck Stevens


moto...@aol.com

unread,
Jun 16, 2004, 8:49:43 AM6/16/04
to
Hi:

Some comments for the old-timers who worked on the 1401 and
those never lucky enough to do so.

If you don't count wiring control panels for EAM machines,
the 1401 was the first machine I programmed and I loved it.

Someone else mentioned the programs to play music. There were
several programs which played music on the printer. The 1403
printer was quite loud and the music would sound different
depending on the type of paper (1-part, 3-part or the special
pink printer-chain cleaning paper). You could also remove the
huge ribbon and run the programs with no paper although I
recall that the IBM CEs frowned on that. There were also programs
which played music which could be heard via a transistor radio
held next to the machine.

The original SPS assembler was a two-pass version which created
an intermediate deck so card-usage was quite spectacular. I
wrote a single-pass assembler when I was working for Independent
News Company, a large magazine distributor in New York which we used
exclusively in place of the IBM assembler.

I also wrote a program to dynamically trace SPS programs and
one to calculate execution times.

When FARGO (Fourteen-Oh-One Automatic Report Generating Operation?)
was introduced, I tried it but didn't like it for whatever reason.
Did it run directly from the source or was there a 'compile' step -
anyone remember? I don't remember if there was RPG for the 1401
or did that come out with the 360?

Although as mathematical as a moose, I also wrote a program to
calculate statistical t-tests which had to calculate square roots
by repetitive division or something. That one gave me lots of
headaches. I still have the listing of that one and samples of
its printed output.

I also wrote a program which allowed the 1401 to play solitaire
by itself. You shuffled the deck and the program read it and
went through the exercise all by itself and printed the final
results. Unfortunately, I don't have the listing for that one
nor samples of its output.

Finally, when the H-200 was introduced I wrote a program to
convert SPS to Easycoder which so impressed Honeywell that
they invited me to Massachusetts to see if I was good enough
to work for them. They didn't hire me so I guess I wasn't.

I still have my original working 1401 and H-200 manuals which
are covered in doodles and notes.

There are some pics of the 1401 at foodman123.com/history

Thanks

Tony Dilworth

Albert Richheimer

unread,
Jun 16, 2004, 12:38:00 PM6/16/04
to
Moto...@aol.com wrote on 16.06.2004, 14:49

M > Someone else mentioned the programs to play music. There were
M > several programs which played music on the printer. The 1403
M > printer was quite loud and the music would sound different
M > depending on the type of paper (1-part, 3-part or the special
M > pink printer-chain cleaning paper). You could also remove the
M > huge ribbon and run the programs with no paper although I
M > recall that the IBM CEs frowned on that. There were also programs
M > which played music which could be heard via a transistor radio
M > held next to the machine.

Here are some songs played on the IBM 1403 printer:
http://www.computerhistory.org/exhibits/highlights/

regards,
Albert (who has used the 1403 back in the early seventies)

Chuck Stevens

unread,
Jun 16, 2004, 1:21:37 PM6/16/04
to
My recollection was that *not all* IBM 1403 printers could be coaxed into
being musical instruments. My recollection is that the (manual-hood, with a
print *chain*) 1403 models 1, 2 and 3 (have I got that right?) could, but
the 1403N1 (automatic-hood, with a print *train*) could not. I believe all
could be


"Albert Richheimer" <richh...@bluewin.ch> wrote in message
news:5C59CBBF2B589...@bluewin.ch...

Chuck Stevens

unread,
Jun 16, 2004, 1:29:33 PM6/16/04
to
Let's try that again.

My recollection was that *not all* IBM 1403 printers could be coaxed into
being musical instruments. My recollection is that the (manual-hood, with a
print *chain*) 1403 models 1, 2 and 3 (have I got that right?) could, but
the 1403N1 (automatic-hood, with a print *train*) could not. I believe all

(including the "Nancy-One" popular on S/360's) could be hooked to 1401's.

-Chuck Stevens


Warren Simmons

unread,
Jun 16, 2004, 9:02:29 PM6/16/04
to
In a string on music on computers, the 1401 has been featured.

I've never heard a 1401 play anything until I tested the files
referenced.

However, with an early number of the Univac I, the maintenance people
brought along tapes made by the Army (I don't know the branch), and
the mounted tapes included many tunes depending upon the sound of
tape read/write on the high speed bus. It's something we could do on
midnights when everything else was caught up. That sound is probably
not available to compare now days, but if we could it would make the
1401 sound roll over dead. Remember these songs were written by out
tax dollars, and served an early sample of what computers are becoming.
Multi-media hounds.

Warren Simmons

Robert Wagner

unread,
Jun 16, 2004, 9:32:07 PM6/16/04
to
"Chuck Stevens" <charles...@unisys.com> wrote:

>
>"Robert Wagner" <robert.d...@wagner.net> wrote in message
>news:40ce1792....@news.optonline.net...
>
>> Every platform I've worked on also uses hardware. But the operating system
>tells
>> the hardware about zones of memory and ids of authorized users.
>
>In the case of Unisys MCP, programs request memory during their initiation.
>The descriptors pointing to that memory are contained within the program's
>stack, and the only processes that can see those descriptors, or the memory
>they point to, are the programs themselves and the MCP. Even the
>descriptors are indirect, as they reference a MCP table that contain the
>*actual* descriptors of the code segments. The only authorized user of a
>space of memory is the process that created it, unless that process
>explicitly provides a path to it (for example, as a parameter to a task or
>library).
>
>> Typically, the
>> zones are "segments" and the user is a "process id". Thus, every called
>program
>> has access to the memory of all other programs within the process .. as
>far as
>> the hardware is concerned.
>
>Nope. Not even close.

I'll take that as a yes. You said the hardware permits a called program to
access its parent's memory. How it gets the address was not in the question.

>> Does Unisys MCP setup user ids smaller than a 'process'?
>
>"User id's" arent germane to Unisys MCP memory management, as I see it. You
>want memory? You build a descriptor template; first time you touch that
>template, the MCP allocates the memory. The descriptor to that memory is in
>*your* stack; nobody else but the MCP can see it, or the memory it
>addresses, unless you pass them the descriptor. You go away? The MCP
>deallocates the memory as part of the process of tearing the stack down.

All operating systems offer a way to dynamically allocate memory, but MCP's way
sounds OOish.

>> Would Unisys MCP or compiler stop this:
>>
>> Program A:
>> 01 bunch-of-pointers.
>> 05 pointer-to-a4 pointer.
>> ...
>
>Umm... Yeah, sure would, at "pointer-to-A4 pointer". I think you're
>laboring under at least one mistaken assumption here.
>
>The Unisys MCP environment currently supports two dialects of COBOL:
>COBOL74, which follows ANSI X3.23-1974, and COBOL85, which follows ANSI
>X3.23-1985 plus the two amendments.
>
>USAGE POINTER was introduced in ISO/IEC 1989:2002 and is an *extension* to
>any implementation of COBOL that conforms to any *prior* standard.
>
>Thus, Unisys MCP software does not recognize the above code as meaningful
>simply because USAGE POINTER isn't in either ANSI X3.23-1974 or ANSI
>X3.23-1985, nor is it implemented as a Unisys extension to either of those
>standards in either of the Unisys MCP COBOL compilers.

So MCP doesn't prevent access, they compiler does by 'hiding' the address.

>Unisys might consider adding USAGE POINTER to the list of 2002-standard
>features for consideration for inclusion in our ANSI-85 compiler, but before
>we could do so we would need at least one Unisys MCP user to let it be known
>to us that they found it a desirable enhancement, and we have not as yet
>been notified of such a request. The enhancements that people have actually
>asked for have to take precedence (for example, INITIALIZE WITH FILLER has
>been requested as a means of improving performance of INITIALIZE).

I wasn't aware the 2002-standard was a Chinese menu .. nor a popular opinion
poll. I thought it was all or nothing.

>The current memory management scheme, and the security it affords our users,
>is a well-liked feature of the Unisys MCP environment that our users have
>liked since our introduction of it in the Burroughs B5000 and through its
>refinement over a number of generations of hardware design. It is not clear
>to us that providing a mechanism whereby users could pretty much arbitrarily
>get to any memory of any component of a run unit without the most local
>"owner" of that memory having any say in the matter would represent an
>improvement in either security or functionality to our existing customers.

I concur that it wouldn't be an improvement for general applications programs,
but contend it would be for systems software charged with diagnosing a failure.

Robert Wagner

unread,
Jun 16, 2004, 9:32:09 PM6/16/04
to
rip...@Azonic.co.nz (Richard) wrote:

>robert.d...@wagner.net (Robert Wagner) wrote
>
>> Would Unisys MCP or compiler stop this:
>> [...]
>> set pointer-to-a4 to address of a4
>> set pointer-to-a5 to address of a5
>> call 'B' using bunch-of-pointers
>> [...]
>> display 'I can see ' a4 ' and ' a5
>
>You seem to assume that just because you can see some parts of the
>memory of the calling program as passed by parameters in a stack frame
>that therefore you would be able to access every other part of that
>program.

That was the question -- whether the hardware prevents access.

>In some cases the Working-Storage of a program is not all one
>contiguous segement. The compiler cannot split 01 levels or 77 levels
>(actually it could as long as the result was logically identical), but
>there is no reason to assume that any or all 01s or 77s are in the
>same segment or have an address that is determinable from the address
>of another, or from a code address such as the return in the stack.
>
>In fact you may not even be able to determine the address of the stack
>frame of the calling program, there is no guarantee that the run-time
>has not created a new stack to pass parameters and return address to
>the program while keeping the caller's stack private.

So protection is afforded by 'information hiding' rather than being
hardware-based.

A widely accepted tenet of computer security is that 'information hiding' and
'secret algorithms' are inadequate and doomed to ultimate failure. The most
robust security systems, such as DES, make their algorithms public.

Robert Wagner

unread,
Jun 16, 2004, 9:32:10 PM6/16/04
to
"Chuck Stevens" <charles...@unisys.com> wrote:

>"Robert Wagner" <robert.d...@wagner.net> wrote in message
>news:40ce3a88....@news.optonline.net...
>
>> In 40+ years Cobol programming, I've never used BY CONTENT (unless the
>called
>> program required it).
>

>Certainly I've used the equivalents in ALGOL and Pascal many a time, and the
>absence of CONTENT / VALUE from ANSI X3.23-1974 was a restriction that
>"bilingual" (ALGOL/COBOL) programmers found decidedly limiting.

You offered nothing supporting or explaining WHY this was a "restriction".

>> >In our environment, if you use CALL <dataname> it is precisely because
>you
>> >expect the contents of <dataname> to change from one execution to the
>next.
>
>> I dispute that. You use it because you want to force dynamic links and the
>> compiler doesn't provide a suitable option such as DYNAM, which makes all
>calls
>> dynamic.
>
>If I understand your definition of "dynamic links", under the Unisys MCP
>implementation of COBOL IPC to separately-compiled programs, *all* such
>CALLs *are* dynamic. Some implementations resolve such things using a
>"linkage editor", as I understand it; the Unisys MCP analog to this is a
>product called "BINDER". For standard COBOL programs, the compilers produce
>*executable code*, directly, period. There is no "post-compilation" step
>other than execution in such a case; BINDER is not involved in ANSI IPC
>calls. At all. Ever.

The Unix analog is 'ld', which is both the static 'linker' and dynamic 'binder'.
In normal default use, all binding is dynamic. Called programs are compiled to
.so, which are dynamically bound.

>I would guess that *both* CALL <literal> *and* CALL <dataname> generate
>"dynamic calls" in this environment by your definition. While it's true
>that the first such CALL is more costly than a call to, say, a
>separately-compiled procedure (which requires non-standard syntax and a
>post-compilation step), once the MCP has initiated the called program and
>established the linkage, the performance is essentially the same, because
>the object code's essentially the same.

Unix works the same way.

>What's different about CALL <literal> and CALL <dataname>? In CALL
><literal> the library template is constructed at compilation time. In CALL
><dataname> the library template must be constructed as part of the object
>code associated with the CALL itself, and destroyed immediately upon return
>from the procedure. That means an InitialPBIT for the library template on
>each CALL and a BLOCKEXIT call to the MCP on each return. That's expensive.

If the systems software was smart, it would cache the previous CALL <dataname>.
If dataname is the same on the next CALL, as it is 99% of the time, the call
would be faster than the first.

>On Unisys MCP systems, if you want to be able to call a separately-compiled
>procedure that has somehow been incorporated into your COBOL object program,
>you don't do it using ANSI IPC calls, you do it through Unisys extensions
>associated with calling procedures that have been incorporated using BINDER.
>This syntax is somewhat similar to the IPC syntax, but not identical. That
>appears to me to be the sense of what I think you'd refer to as a "static
>link" -- a link established after compilation but before execution. You can
>do it on our system, but it's not part of the ANSI IPC implementation.

I can't tell from your response whether ANSI IPC favors dynamic or static links.
I would guess dynamic because that's favored by Unix, NT and most other modern
operating systems.

>> In the Unix world, late binding is the default.
>
>In the Unisys MCP world as it relates to ANSI IPC to separately-compiled
>programs, binding occurs on first CALL, period. There is no "early" or
>"late" in the ANSI IPC context, there is only the linkage established by the
>MCP at execution time. If you want "early" binding, then don't use ANSI IPC
>syntax, use declaratives with USE EXTERNAL, bind the procedure in, and use
>CALL <section-name>.

Ok, ANSI IPC and MCP are both late binding, despite your protestations.

>> Other languages discourage or outright prohibit passing large structures
>on the
>> stack. That's the provenance of malloc (intra-process) or Shared Memory
>(across
>> processes). The caller is expected to allocate a chunk and pass a pointer
>to it.
>
>What other languages -- from ALTAC to C# -- do or did and how and why they
>did it is not necessarily germane to the design and history of, or
>requirements for, COBOL. Pascal allows all sorts of stuff that neither
>Fortran66 nor RPG allow, and prohibits stuff that even COBOL(68) thought was
>the bee's knees. What's your point?

My point was modern operating systems, not obsolete languages.

>If your expectation is that all implementations "allocate a chunk and pass a
>pointer to it", all I can say is the advice some wise friends gave me: "an
>expectation is a premeditated resentment". The code generated for the call
>may be expected *by you* to look the way you want it to and to make the data
>available to the called routine in a particular fashion, but that's your
>expectation, to which you are welcome, and that expectation does not
>necessarily have anything to do with general reality.

Too obtruse to reply.


Robert Wagner

unread,
Jun 16, 2004, 9:32:11 PM6/16/04
to
"Chuck Stevens" <charles...@unisys.com> wrote:

>"Robert Wagner" <robert.d...@wagner.net> wrote in message
>news:40ce1f14....@news.optonline.net...
>
>> If a program couldn't access its own stack, it wouldn't be able to return
>from a
>> call.
>
>Silly me. I was under the impression that the EXIT (or RETN) hardware
>operators, with a RCW on the stack placed there by the caller and invisible
>to the called routine, handled that. Must've been wrong all these years.

Silly me. I thought the hardware afforded protection independent of language.
Now you claim the language's 'hiding' features make the stack invisible to
'application code'.

Obviously, we'll have to deny application programmers access to languages that
generate an EXIT or RETN, especially assembly language. That would be easy on
Unisys because there is no assembly language.

Tying programmers' hands is even worse security than 'information hiding'.

>> If it couldn't access the caller's stack, this wouldn't work:
>>
>> Program A: call 'B' using by content a1
>> Program B: display "A's stack is at " address of a1
>
>Could you point out to me once again where "address of" appears in ANSI
>X3.23-1985 (or, for that matter ANSI X3.23-1974)?

It doesn't, but it appears in IBM, Micro Focus, Fujitsu and others. In other
words, 98+% of available Cobol compilers.

Robert Wagner

unread,
Jun 16, 2004, 9:32:12 PM6/16/04
to
"Chuck Stevens" <charles...@unisys.com> wrote:

>
>"Robert Wagner" <robert.d...@wagner.net> wrote in message
>news:40ce2169....@news.optonline.net...
>

>> Near the beginning of this thread, we discussed identifying programs in


>error
>> messages. I opined that the error reporting mechanism should walk back the
>stack
>> reporting the names of all programs leading to one of interest.
>
>No, perhaps *you* discussed identifying programs in error messages; I don't
>recall having participated in that part of the discussion.

The original poster recently confirmed that my guess was correct, he wanted to
identify the offending program in an error message.

>In our case, because the fundamental architecture of the system is
>stack-based to begin with, identifying the history from the point of failure
>all the way through all the nested calls is handled. Names are available
>for separately-compiled programs, but COBOL programs in the Unisys MCP
>environment typically have unique sequence numbers for each source line, a
>nested program forms part of a compilation unit, and the sequence numbers
>(together, sometimes, with the code address in the RCW) provides enough
>information for the user to figure out the calling sequence that led to the
>failure. The program-id of a nested program may show up, but that's not
>what people used to working with Unisys MCP COBOL85 use as a primary
>debugging tool.

Clear as mud. Just tell me the name of the failed program and line number on
which it failed. Given that, I can figure out why it failed. Do I ask too much?

Richard

unread,
Jun 17, 2004, 1:41:18 AM6/17/04
to
robert.d...@wagner.net (Robert Wagner) wrote

> The original poster recently confirmed that my guess was correct, he wanted to
> identify the offending program in an error message.

Your memory is selective or, possibly, failing:

RP >> >That is not going to show the name of any CALLed programs,
which is
RP >> >probably the point of the request.

RW >> No, he wants the name of the Main program,

If you are not trolling, then your messages are becoming increasingly
indistinguishable from that.

docd...@panix.com

unread,
Jun 17, 2004, 5:17:53 AM6/17/04
to
In article <40d0bf9d...@news.optonline.net>,

Robert Wagner <robert.d...@wagner.net> wrote:
>"Chuck Stevens" <charles...@unisys.com> wrote:
>
>>
>>"Robert Wagner" <robert.d...@wagner.net> wrote in message
>>news:40ce1792....@news.optonline.net...

[snip]

>>> Typically, the
>>> zones are "segments" and the user is a "process id". Thus, every called program
>>> has access to the memory of all other programs within the process .. as far as
>>> the hardware is concerned.
>>
>>Nope. Not even close.
>
>I'll take that as a yes.

Mr Wagner, at times you've mentioned how some folks have... difficulties
when discussing things with you. The above might, if pondered, give an
indication towards a reason.

DD

Robert Wagner

unread,
Jun 17, 2004, 6:19:05 AM6/17/04
to
docd...@panix.com wrote:

I've learned that attempts to find common ground by clarifying or adding
information are fruitless here. They work in face-to-face conversation but not
in electronic communication. Thus, I responded to the information given. The
question was 'Does the hardware prevent a called program from accessing its
parent's memory?' Mr. Stevens' response, deleted here, said it does not.

docd...@panix.com

unread,
Jun 17, 2004, 7:31:05 AM6/17/04
to
In article <40d16df7...@news.optonline.net>,

Robert Wagner <robert.d...@wagner.net> wrote:
>docd...@panix.com wrote:
>
>>In article <40d0bf9d...@news.optonline.net>,
>>Robert Wagner <robert.d...@wagner.net> wrote:
>>>"Chuck Stevens" <charles...@unisys.com> wrote:
>>>
>>>>
>>>>"Robert Wagner" <robert.d...@wagner.net> wrote in message
>>>>news:40ce1792....@news.optonline.net...
>>
>>[snip]
>>
>>>>> Typically, the
>>>>> zones are "segments" and the user is a "process id". Thus, every called program
>>>>> has access to the memory of all other programs within the process .. as far as
>>>>> the hardware is concerned.
>>>>
>>>>Nope. Not even close.
>>>
>>>I'll take that as a yes.
>>
>>Mr Wagner, at times you've mentioned how some folks have... difficulties
>>when discussing things with you. The above might, if pondered, give an
>>indication towards a reason.
>
>I've learned that attempts to find common ground by clarifying or adding
>information are fruitless here. They work in face-to-face conversation but not
>in electronic communication.

Mr Wagner, from what little experience that I have in face-to-face
conversation to respond to 'Nope. Not even close.' with 'I'll take that
as a yes.' has a tendency to cause the negating party to respond with
something along the lines of 'I'm sorry, were your parents blood
relatives? I said 'No'; you can take that as an apple strudel, if you so
desire, but what you are claiming to take it as is the exact opposite of
what I gave it as.'

If you are not 'attempting to find common ground by clarifying or adding
information', Mr Wagner, then what *are* you trying to do?

DD

Chuck Stevens

unread,
Jun 17, 2004, 12:22:37 PM6/17/04
to

"Robert Wagner" <robert.d...@wagner.net> wrote in message
news:40d0bf9d...@news.optonline.net...

No, you misunderstood. The hardware permits a called (separately-compiled)
program to access the parameters that the caller passed to it, and data
items that are declared EXTERNAL. The hardware permits a called (nested)
program to access the parameters that the caller passed to it, variables
declared GLOBAL in higher nesting levels, and data items that are declared
EXTERNAL.

> All operating systems offer a way to dynamically allocate memory, but
MCP's way
> sounds OOish.

More like OO sounds MCP-ish. This mechanism has been in daily use since the
introduction of the Burroughs B5000 in 1959. The hardware was originally
designed around the semantics of ALGOL, and implements a "just-in-time"
approach to memory management in which memory isn't allocated until it's
actually referenced for the first time, and the resources associated with a
procedure disappear automatically or are disappeared by the oerating system
when the procedure is executed unless explicit steps are taken to do
otherwise. I'm reasonably certain that Object Orientation as a software
development regimen rather postdates the introduction of ALGOL.

> So MCP doesn't prevent access, they compiler does by 'hiding' the address.

No, the compiler doesn't "hide" the address; neither the compiler nor the
program ever has reason to *know* the address. All it has is a descriptor,
and if it doesn't explicitly pass the descriptor to that memory space to
somebody else, that somebody else can't see it.

> I wasn't aware the 2002-standard was a Chinese menu .. nor a popular
opinion
> poll. I thought it was all or nothing.

The 2002 standard is indeed all or nothing if the compiler you are
implementing claims to be conformant with the 2002 standard. Many
implementations take features of a standard and incorporate them *as
extensions* to compilers conformant with *previous* standards. In this
case, I was discussing the efficacy of *extending* a compiler compliant with
ANSI X3.23-1985 to include the USAGE POINTER as described in a *later*
standard. We did the same when the Indexed I/O module was standardized in
the '74 standard -- we incorporated the same syntax into our COBOL(68)
compiler.

> I concur that it wouldn't be an improvement for general applications
programs,
> but contend it would be for systems software charged with diagnosing a
failure.

Well, yeah ... the MCP, which has access to the entire system because it has
special privileges, decodes this information on behalf of the diagnostic
software. The problem with that is ... ?

-Chuck Stevens


Chuck Stevens

unread,
Jun 17, 2004, 12:37:12 PM6/17/04
to

"Robert Wagner" <robert.d...@wagner.net> wrote in message
news:40d0da71...@news.optonline.net...

> So protection is afforded by 'information hiding' rather than being
> hardware-based.

No, that's not it. Memory is only accessible through descriptors and
according to the hardware scope rules of execution level. Nothing but the
ASD initialization process deals with "real" memory addresses. The ASD
table is not actively "hidden"; the scope rules of the hardware simply mean
that it's not visible to anybody but the MCP. There is no hardware
mechanism to access memory spaces except through descriptors, and unless the
user has visibility to that descriptor (through scope rules or through
direct means) the user can't see the memory. A user application program
cannot explicitly *manipulate* its own stack, much less any other, nor has
it any means to deal with raw memory addresses.

There are lots of discussions on the web about the architecture of the
Burroughs B5000 and its evolution into the Burroughs B6700; they'd be a much
better source of how this all works than I.

-Chuck Stevens


Chuck Stevens

unread,
Jun 17, 2004, 1:22:08 PM6/17/04
to

"Robert Wagner" <robert.d...@wagner.net> wrote in message
news:40d0eaff...@news.optonline.net...

> Clear as mud. Just tell me the name of the failed program and line number
on
> which it failed. Given that, I can figure out why it failed. Do I ask too
much?

Unisys MCP COBOLs don't deal in *line* numbers, they deal in *sequence*
numbers (remember columns 1-6?).

Given that, for a system consisting exclusively of separately-compiled COBOL
programs, the program dump provides the object code file name of the
compilation unit and the sequence number and actual object code instruction
address of the failure for each level in the PERFORM and CALL stack history.

For a program that's nested, the sequence numbers identify the location of
the failure, the call history within the compilation unit, the object code
file name of the compilation unit, and the actual object code instruction
address for of the failure for each level in the PERFORM and CALL stack
history.

The sequence number history of any failure is also by default provided in
the abnormal-termination message, though you may actually have to glance at
the program dump to find out which sequence number goes with which program.

Have you *demonstrated* that you need more information than the MCP has
already provided *you*? Or is it just "I want to do it *my* way, not the
way the system allows me to do it!"?

-Chuck Stevens


Chuck Stevens

unread,
Jun 17, 2004, 1:15:17 PM6/17/04
to

"Robert Wagner" <robert.d...@wagner.net> wrote in message
news:40d0e65d...@news.optonline.net...

> Silly me. I thought the hardware afforded protection independent of
language.
> Now you claim the language's 'hiding' features make the stack invisible to
> 'application code'.

EXIT, RETN, and the setting of the RCW on ENTR are independent of language.
The hardware scope rules and the D registers are independent of language.

> Obviously, we'll have to deny application programmers access to languages
that
> generate an EXIT or RETN, especially assembly language. That would be easy
on
> Unisys because there is no assembly language.

Application programs cause the compilers to generate EXIT, RETN, MKST and
ENTR all the time. What application programs cannot do is make use of raw
memory addresses, access other programs' stacks, or even access their own
stack as if it were data and "leapfrog" from there into a stack owned by
another process.

Moreover, precisely because memory *is* dynamically allocated, there is no
guarantee from one access to the next that a given piece of information will
be in the same physical location, so *raw* memory addresses are meaningless.


If you could decode a RCW or access the stack directly as if it were a
memory space, what would you do with that information, given that even that
space is protected by the scope rules?

> Tying programmers' hands is even worse security than 'information hiding'.

Users are welcome to write their own compilers. However, it is the compiler
author's responsibility to ensure that the code it generates is compatible
with all currently-supported machines, and there is no guarantee that a
given convention or approach to a process will survive for any period of
time. And if a user elects to change one of our compilers, any problem they
report in that language must be reproduced by them using, and reported
against, a released compiler; we do not support software that has been
locally patched.

Why is it necessary for a user program to have access to another process'
memory space without that process' direct involvement in the access? So
far as I know, very few, if any, actual *users* of this architecture have
found the mechanisms of memory management and the stack architecture
*restrictive*.

> > It doesn't, but it appears in IBM, Micro Focus, Fujitsu and others. In
other
> words, 98+% of available Cobol compilers.

Are we using the adolescent argument "But MOM!!!! Everybody who's *ANYbody*
has one!", eh? Or are we back to "What is or is not standards-compliant
COBOL has nothing to do with what the standards say, only with what I
perceive to be Admirable Practice!"?

Again, any Unisys MCP customer is welcome to file a New Feature Suggestion
against COBOL85 to request USAGE POINTER in that dialect. I daresay IBM,
Micro Focus, Fujitsu and others have incorporated it because *their*
customers have found it to be a useful feature. As far as ANSI X3.23-1985
COBOL goes, it is an extension, and in our case there has been so little
demand for this extension from our users -- that is to say, none -- and
there has been so little evidence that this feature would be of particular
benefit in the Unisys MCP environment -- none that I've seen so far, and a
lot of security risks -- that it isn't even on the list of such features for
consideration at this time.

-Chuck Stevens


Richard

unread,
Jun 17, 2004, 3:38:21 PM6/17/04
to
robert.d...@wagner.net (Robert Wagner) wrote

> >>>> Typically, the
> >>>> zones are "segments" and the user is a "process id". Thus, every called
> program
> >>>> has access to the memory of all other programs within the process .. as far
> as
> >>>> the hardware is concerned.
> >>>
> >>>Nope. Not even close.
> >>
> >>I'll take that as a yes.
> >
> >Mr Wagner, at times you've mentioned how some folks have... difficulties
> >when discussing things with you. The above might, if pondered, give an
> >indication towards a reason.

> I've learned that attempts to find common ground by clarifying or adding
> information are fruitless here.

The only way that common ground can be found is by _learning_ what the
other party's experience and knowledge is. When there are things that
are outside your experience and knowledge then you 'adding
information' just doesn't work, it is just contradicting what they
know to be true (and know that you don't know).

> They work in face-to-face conversation but not
> in electronic communication. Thus, I responded to the information given. The
> question was 'Does the hardware prevent a called program from accessing its
> parent's memory?' Mr. Stevens' response, deleted here, said it does not.

You fail to distinguish between 'accessing the passed parameters from
the parent' and your assertion about: "access to the memory of all


other programs within the process".

Just because the hardware allows a small amount of specific access
does not mean that therfore it allows complete and unrestricted
access. An issue here is addressability. A CALLed program is passed
the address of some specific areas as parameters. You may be used to
being able to calculate the addresses of other areas from that, but
that is not necessarily a valid assumption in other architectures.

Even in a lowly 80286 it is possible to create a new descriptor that
allows access to an area of data but which bears no relationship to
descriptors which access other data. For example on doing a CALL the
run-time (or generated code) could create a descriptor for each
parameter and pass pointers referenceing those. This would give free
access to the parent(s)' data areas being passed by reference while
enforcing hardware restrictions beyond those boundries.

Chuck Stevens

unread,
Jun 17, 2004, 3:44:05 PM6/17/04
to

"Robert Wagner" <robert.d...@wagner.net> wrote in message
news:40d0ddc7...@news.optonline.net...

I wrote:

> >Certainly I've used the equivalents in ALGOL and Pascal many a time, and
the
> >absence of CONTENT / VALUE from ANSI X3.23-1974 was a restriction that
> >"bilingual" (ALGOL/COBOL) programmers found decidedly limiting.

Robert responded:

> You offered nothing supporting or explaining WHY this was a "restriction".

I thought that was self-explanatory. ANSI X3.23-1974 requires parameters to
be passed by reference and requires that the called program be able to
modify those parameters as they exist in the calling program.

By contrast, ALGOL allows VALUE, NAME or REFERENCE parameters. VALUE is
conventional and preferred; the others allow access to the caller's
instantiations of the data.

The inability to CALL an ALGOL program that has a VALUE parameter from
COBOL74 stems from the fact that ANSI X3.23 requires that COBOL74 programs
be able to modify the caller's instantiation, and the ALGOL VALUE syntax
prevents that. The result is a failure when the MCP attempts to link the
library to the program because the parameter descriptions in the two library
templates are incompatible.

> If the systems software was smart, it would cache the previous CALL
<dataname>.

Well, it might. But it's not clear that it's smart to do so.

> If dataname is the same on the next CALL, as it is 99% of the time, the
call
> would be faster than the first.

Where on earth did you get *that* statistic? The whole point of CALL
<dataname> is that the programmer *doesn't* know what the name of the called
program is going to be until he gets to the CALL statement! If 99% of the
time it's the same, why not use CALL <literal>? Or even CHANGE ATTRIBUTE
TITLE OF <libraryname> TO <newlibname> CALL <newlibname>? Both are a whole
lot faster than CALL <dataname>!

> I can't tell from your response whether ANSI IPC favors dynamic or static
links.
> I would guess dynamic because that's favored by Unix, NT and most other
modern
> operating systems.

I'm not sure the standard cares, but I would suggest that the Unisys MCP
implementation, which requires no post-compile pre-execution steps and uses
dynamic links, matches both the spirit and the letter of the ANSI spec in
this fashion. A compiled COBOL74 program is ready to execute in our
environment as soon as the compiler's locked the file in the disk directory,
whether that execution is "manual" or as a called program in a COBOL74 run
unit. That's the convention on Unisys MCP systems, where a "linking"
process is very much the exception and is always carefully considered in
application design. On systems where a "link" step is usual or even
mandatory, it wouldn't be surprising for ANSI IPC handling to include such a
step, but that's not the case on Unisys MCP systems, and a bind (or rebind)
during every compilation would be regarded by most Unisys MCP users as
extremely tedious and contrary to their expectations.

> Ok, ANSI IPC and MCP are both late binding, despite your protestations.

ANSI COBOL IPC *as such* does not state anything about "binding", much less
what time it should occur. But Unisys believes their users expect programs
to be ready for use when the *compiler* is finished producing them, which
means that the only time binding occurs for ANSI IPC calls (and for "library
linkages") in the MCP environment is during execution, at the first CALL to
the program.

What you call "early binding" is something entirely different -- external
subprograms -- and MCP supports that too, but not using ANSI IPC syntax or
mechanisms.

The distinction "early" vs. "late" may apply to Unix. It may apply to IBM.
But it is simply not meaningful in the Unisys MCP environment when it comes
to a *single* CALL mechanism. If you want called routines to be linked
*before* execution -- in which case they form a single object code file with
the caller -- then you specify USE EXTERNAL and CALL <section-name>. That,
in MCP terminology, is called "using bound procedures". Many do that. If
you want the ability to replace the called program on the fly, then you can
use ANSI IPC syntax or minor extensions to it. That, in MCP terminology, is
called "using library calls".

> My point was modern operating systems, not obsolete languages.

What COBOL does is what COBOL is defined to do. The COBOL standards do not
specify the manner in which a CONTENT parameter is passed, only that the
called program has access to it. That some languages have explicit "heap
manipulation" syntax and others have explicit memory allocation syntax is
all well and good, but it's not clear to me that the lack of such features
in a given language renders that language obsolete!

I might even be inclined to agree with you in this: Any operating
environment that passes a parameter by reference to a called routine does so
using a descriptor occupying a single 48-bit word with tag bits containing
5, visible only to the process in which it was declared and to the caller,
pointing to an entry in the ASD table maintained by the operating
environment (and visible only to the operating environment and the hardware)
that describes the actual memory space. Any operating environment that
passes a numeric parameter by value to a called routine does so by placing
the numeric value on the stack where it is visible to the called routine.
Any operating environment that doesn't handle calling processes in this way
is hopelessly obsolete and richly deserves to be cast onto the dustbin of
history! ;-) But that's only my opinion, not a statement ex cathedra
papae!

> Too obtruse to reply.

Hey, you're the one that has decided in his infinite wisdom, how *all*
environments ought to work! Passing some sort of something that might be
described as a pointer *might* be a reasonable approach in general, but I
can certainly come up with exceptions and environments in which other
approaches could be preferable!

-Chuck Stevens
>
>


Russell Styles

unread,
Jun 17, 2004, 4:44:49 PM6/17/04
to

"Warren Simmons" <wsim...@optonline.net> wrote in message
news:40D0ED8C...@optonline.net...

> In a string on music on computers, the 1401 has been featured.
>
> I've never heard a 1401 play anything until I tested the files
> referenced.
>
> However, with an early number of the Univac I, the maintenance people
> brought along tapes made by the Army (I don't know the branch), and
> the mounted tapes included many tunes depending upon the sound of
> tape read/write on the high speed bus. It's something we could do on
> midnights when everything else was caught up. That sound is probably
> not available to compare now days, but if we could it would make the
> 1401 sound roll over dead. Remember these songs were written by out
> tax dollars, and served an early sample of what computers are becoming.
> Multi-media hounds.
>
> Warren Simmons
>

In the 1972 - 1976 period, The university of Georgia (Athens)
had two old computers. One was a 1401, which was used almost
entirely as another printer at that point. If they had any musical
print jobs, I never heard about it.

But they also had another (much) older IBM, I forget the model number
(Something 01?). It was a three digit number, and used tape drives
entirely. It had the ability to make music internally, the cooling system I
think.

As near as I could tell, all that it did was take up space, and play
music for tour groups. They scrapped it while I was there.


Robert Wagner

unread,
Jun 17, 2004, 8:30:27 PM6/17/04
to
docd...@panix.com wrote:

My reason for being here is to promote Cobol as a Real Programming Language
rather than the travesty that mainframers have turned it into.

Robert Wagner

unread,
Jun 17, 2004, 8:30:39 PM6/17/04
to
"Russell Styles" <rws...@comcast.net> wrote:


> But they also had another (much) older IBM, I forget the model number
>(Something 01?). It was a three digit number, and used tape drives
>entirely. It had the ability to make music internally, the cooling system I
>think.

The 1401 didn't have a cooling system. Music came from Core Storage, made from
actual ferrite cores, playing through an FM radio.

The first program I ever wrote read a 'script' on punched cards containing notes
and durations. One could keypunch a musical script and hear it played by the
1401. I was working on harmonics when the project ended.

docd...@panix.com

unread,
Jun 17, 2004, 9:30:54 PM6/17/04
to
In article <40d23662....@news.optonline.net>,

Robert Wagner <robert.d...@wagner.net> wrote:
>docd...@panix.com wrote:
>
>>In article <40d16df7...@news.optonline.net>,
>>Robert Wagner <robert.d...@wagner.net> wrote:

[snip]

>>>I've learned that attempts to find common ground by clarifying or adding
>>>information are fruitless here. They work in face-to-face conversation but not
>>>in electronic communication.
>>
>>Mr Wagner, from what little experience that I have in face-to-face
>>conversation to respond to 'Nope. Not even close.' with 'I'll take that
>>as a yes.' has a tendency to cause the negating party to respond with
>>something along the lines of 'I'm sorry, were your parents blood
>>relatives? I said 'No'; you can take that as an apple strudel, if you so
>>desire, but what you are claiming to take it as is the exact opposite of
>>what I gave it as.'
>>
>>If you are not 'attempting to find common ground by clarifying or adding
>>information', Mr Wagner, then what *are* you trying to do?
>
>My reason for being here is to promote Cobol as a Real Programming Language
>rather than the travesty that mainframers have turned it into.

I see... and you expect to do this without 'attempting to find common
ground by clarifying or adding information'.

What's left, one might wonder... cunningly-wrought insults or sheer Force
of Personality?

DD

Richard

unread,
Jun 17, 2004, 10:44:29 PM6/17/04
to
robert.d...@wagner.net (Robert Wagner) wrote

> It doesn't, but it appears in IBM, Micro Focus, Fujitsu and others. In other
> words, 98+% of available Cobol compilers.

Let me see now. "Available Cobol compilers", here are some:

Microfocus
Liant
AcuCobol
IBM
Fujitsu
Kobol
OpenCobol
HP Cobol
Compaq NonStop

The one you mentioned seems to be about 33% of this list.

Perhaps you meant something else, again.

Russell Styles

unread,
Jun 17, 2004, 11:11:24 PM6/17/04
to

"Robert Wagner" <robert.d...@wagner.net> wrote in message
news:40d2346e....@news.optonline.net...

I didn't say anything about music and the 1401. The music was generated
by the (much) older IBM.


Hugh Candlin

unread,
Jun 18, 2004, 12:38:34 AM6/18/04
to

Russell Styles <rws...@comcast.net> wrote in message news:9LadnWHjfYV...@giganews.com...

>
> In the 1972 - 1976 period, The university of Georgia (Athens)
> had two old computers. One was a 1401, which was used almost
> entirely as another printer at that point. If they had any musical
> print jobs, I never heard about it.
>
> But they also had another (much) older IBM, I forget the model number
> (Something 01?). It was a three digit number, and used tape drives
> entirely. It had the ability to make music internally, the cooling system I
> think.

Does this look familiar?

http://www-1.ibm.com/ibm/history/exhibits/701/701_141511.html

http://www-1.ibm.com/ibm/history/exhibits/701/701_141512.html


Richard

unread,
Jun 18, 2004, 2:06:14 AM6/18/04
to
"Chuck Stevens" <charles...@unisys.com> wrote

> > If dataname is the same on the next CALL, as it is 99% of the time, the
> call
> > would be faster than the first.
>
> Where on earth did you get *that* statistic? The whole point of CALL
> <dataname> is that the programmer *doesn't* know what the name of the called
> program is going to be until he gets to the CALL statement! If 99% of the
> time it's the same, why not use CALL <literal>? Or even CHANGE ATTRIBUTE
> TITLE OF <libraryname> TO <newlibname> CALL <newlibname>? Both are a whole
> lot faster than CALL <dataname>!

I have several systems where the 'main' program is a simple loop which
is roughly:

MOVE Logon-Program TO Program-Name
MOVE Menu-Program TO Next-Program
PERFORM
UNTIL Program-Name = "FINISH"

CALL Program-Name
USING <interface block that includes Program-Name
and Next-Program>
ON EXCEPTION ...
END-CALL
CANCEL Program-Name
MOVE Next-Program TO Program-Name
MOVE Menu-Program TO Next-Program
END-PERFORM

Any program can change Next-Program to allow the user or any program
to control where the system goes without having to return to the menu,
which is just the default action.

The chances of the same program being CALLed twice in a row is very
small.

Richard

unread,
Jun 18, 2004, 2:42:38 AM6/18/04
to
robert.d...@wagner.net (Robert Wagner) wrote

> >If you are not 'attempting to find common ground by clarifying or adding
> >information', Mr Wagner, then what *are* you trying to do?
>
> My reason for being here is to promote Cobol as a Real Programming Language
> rather than the travesty that mainframers have turned it into.

I'd be interested in what way you think that mainframers have 'turned
it into a travesty'. It may well be that some mainframers are still
using it in much the same way that it has been used for 25 or even 45
years, but this has _retained_ its origins and not changed it into
something completely different.

Cobol always has been a 'real language' but trying to turn it into C
or a second rate Java is a mistake (IMHO). Its major strength is that
code has continued to be used and reused for decades and can continue
to do so where it still meets the business needs.

C++, Java, C#, VB programmers are irrelevant to Cobol, they will use
what is the current trend and then move on to the next. They will
never be interested in Cobol, and if they became so they would soon
move on to something else anyway.

Chuck Stevens

unread,
Jun 18, 2004, 1:39:42 PM6/18/04
to

"Robert Wagner" <robert.d...@wagner.net> wrote in message
news:40d16df7...@news.optonline.net...

> I've learned that attempts to find common ground by clarifying or adding
> information are fruitless here. They work in face-to-face conversation but
not
> in electronic communication. Thus, I responded to the information given.
The
> question was 'Does the hardware prevent a called program from accessing
its
> parent's memory?'
>
>Mr. Stevens' response, deleted here, said it does not.

No, Mr. Wagner, that's not correct, that wasn't what I responded to.

You asserted:

<<Typically, the zones are "segments" and the user is a "process id". Thus,
every called
program has access to the memory of all other programs within the process ..
as
far as the hardware is concerned >>

I cited that set of assertions and the conclusion you drew from it, and
replied:

<<Nope. Not even close.>>

Your assertions, as well as your conclusion, is what I was addressing. Both
initial assertions are incorrect on Unisys MCP systems, and the conclusion
does not follow from the assertions even if the assertions were general
truths.

I quoted that particular text immediately before my response precisely
because that's what I was responding to.

You may certainly take "Nope. Not even close." as a "Yes" if you like.
You make take it as a "tuesday" or a "Chevrolet" or as any word in any part
of speech you wish, but if you take it as anything but "Nope. Not even
close." you're living in a castle in the air that you built.

On Unisys MCP systems, a called *separately-compiled* program has access,
besides to its local data, only to those data items declared EXTERNAL in the
caller or passed to the called program as parameters by the caller. A
called *nested* program in that environment has access to those categories,
plus any data items declared GLOBAL in a "shallower" nesting level within
the compilation unit.

Because the contents of a memory space are not visible or addressible unless
a descriptor pointing to that memory space is visible, and because each
memory space has its own descriptor, a called program does *not* have access
to any memory space owned by the caller unless the caller explicitly makes
it visible (as EXTERNAL, or as a parameter, or as GLOBAL in the case of
nested programs) by having a descriptor individually, and explicitly,
provided to it.

Of these, the only one that's a *software* convention is access to a
shallower nesting level's non-GLOBAL data space by a nested program, and the
compiler knows which stack cells are allocated for local data for shallower
levels. Access to such item is not allowed simply because the *compiler*
"forgets" at the deeper nesting level, what the stack cells associated with
local data at shallower nesting levels are used for, remembering only that
they're in use elsewhere and skipping them during allocation of cells at the
deper nesting level. Since the descriptor of a shallower program's local
data isn't in the nested program's stack space, the nested program has no
access to it.

You may want to think that a called program can get to, for example, all of
its caller's WORKING-STORAGE if it has access to any of it, because
everybody knows that a program's data space is monolithic and contiguous in
all implementations. And there may be implementations and environments in
which that's the case. But that isn't the way either the hardware or the
software works on Unisys MCP systems.

Allocation of memory space is secondary to having an untouched data
descriptor to begin with. The only way to gain access to a preexisting
memory space -- which means that the memory space has been touched -- is to
have access to the already-built descriptor that points to it. If the
compiler doesn't provide that access (through EXTERNAL, through GLOBAL, or
as a parameter), the called process doesn't get access to the memory.
Having access to another memory space in the memory space in the same
calling program is absolutely irrelevant, because that memory space is
governed by a *different* descriptor. The hardware *design* prevents
access to other portions of the caller's memory by the simple expedient of
"you can't get there from here". Neither the hardware nor the software
*actively prevents* anything; it's the *access* that has to be granted
*explicitly* to begin with.

-Chuck Stevens


Russell Styles

unread,
Jun 18, 2004, 7:32:02 PM6/18/04
to

"Hugh Candlin" <n...@spam.com> wrote in message
news:eluAc.88047$Gx4....@bgtnsc04-news.ops.worldnet.att.net...
Could be. I don't imagine that there were TOO many IBM's that were tape
based.

It would be better if someone that had access to the machine room back then
replied.


Robert Wagner

unread,
Jun 18, 2004, 8:37:20 PM6/18/04
to
docd...@panix.com wrote:

..Demos of well-written code using Advanced Features such as multithreading and
OO.
..Rebuttal against the forces of darkness, so readers know there is an
alternative.

PECD uses Force of Personality very effictively, I think. The rest of us code
crankers must rely on facts, code samples or emotion to be Validated.

Robert Wagner

unread,
Jun 18, 2004, 8:37:19 PM6/18/04
to
rip...@Azonic.co.nz (Richard) wrote:

>robert.d...@wagner.net (Robert Wagner) wrote
>
>> >If you are not 'attempting to find common ground by clarifying or adding
>> >information', Mr Wagner, then what *are* you trying to do?
>>
>> My reason for being here is to promote Cobol as a Real Programming Language
>> rather than the travesty that mainframers have turned it into.
>
>I'd be interested in what way you think that mainframers have 'turned
>it into a travesty'. It may well be that some mainframers are still
>using it in much the same way that it has been used for 25 or even 45
>years, but this has _retained_ its origins and not changed it into
>something completely different.

But it has, at least once. When Structured Programming appeared in the late
'60s, we already had a substantial body of work based on GO TO. Had this forum
existed then, I can picture heated debates between the Old Guard defending GO TO
and bright-eyed 'progressives' decrying GO TO. For once, the good guys won,
although we still see backguard pockets of resistance some 35 years later.

What happened to that spirit of improvement? OO Cobol is roughly comparable to
Structured Programming back then. Why has it been ignored by the Cobol
community? Because we're now aged 50-60 rather than 20-30? Or is it because
mainframe shops have Programming Standards prohibiting progress? (pardon
alliteration)

>Cobol always has been a 'real language' but trying to turn it into C
>or a second rate Java is a mistake (IMHO). Its major strength is that
>code has continued to be used and reused for decades and can continue
>to do so where it still meets the business needs.

I don't think pointers make Cobol C-like; I think they make it equally capable.
Before compilers 'extended the Standard' to support pointers, we did it with
calls to assembly language programs that modified 'BLL cells'. Pointers are an
essential tool. Their absence in Java and C# is a serious limitation to those
cultures.

There is merit in resistance to change. It goes to the difference between
evolution and revolution. See for example Alexander's "Notes on the Synthesis of
Form", published by Harvard Press.The book deals with design of a tea kettle,
but the principles involved embrace all architecture and computer systems.

FWIW, I have a tea kettle that boils water four times faster than microwave, on
an ordinary gas stove.

Resisting progress is one thing, arguably good; ignoring and rejecting it is
Bad. Cobol's strength doesn't come from immutability, it comes from
extensibility. OO Cobol is a good demonstration of the language's vibrancy ..
and its adherents' resistance to progress.

>C++, Java, C#, VB programmers are irrelevant to Cobol, they will use
>what is the current trend and then move on to the next. They will
>never be interested in Cobol, and if they became so they would soon
>move on to something else anyway.

I agree -- diletantes will not stick with Cobol. Good riddance.

Clark F. Morris, Jr.

unread,
Jun 18, 2004, 8:55:49 PM6/18/04
to
Robert Wagner wrote:
> "Chuck Stevens" <charles...@unisys.com> wrote:
>
>
>>"Clark F. Morris, Jr." <cfm...@istar.ca> wrote in message
>>news:cag4bh$j8c$1...@news.eusc.inter.net...
>>
>> snip >>>


> Let's call this hypothetical machine CADET, for Can't Add, Doesn't Even Try. It
> could do arithmetic by table lookup using two indicies. The RCA 301 actually
> worked that way. If someone stepped on the arithmetic table at a fixed address
> in low memory, answers came out wrong until you rebooted the machine.
>
Where were the add tables? I know that the print translate table was in
high memory (19900-63 as I recall) because we had a program space fill
the table causing the Analex (sp?) drum printer to print and blow a
fuse. Translate instructions used tables that started at 00 locations.
>> rest snipped

docd...@panix.com

unread,
Jun 18, 2004, 9:39:36 PM6/18/04
to
In article <40d38256....@news.optonline.net>,

That would appear to constitute 'adding information', Mr Wagner, and you
have already admitted that you are not trying to do this.

>..Rebuttal against the forces of darkness, so readers know there is an
>alternative.

Those rebuttals, however, must be devoid of 'attempting to find ground by
clarifying or adding information'... hence my question still stands.

>
>PECD uses Force of Personality very effictively, I think. The rest of us code
>crankers must rely on facts, code samples or emotion to be Validated.

What someone else does, Mr Wagner, is their own concern... and 'facts
(and) code samples', in that they are attempts to communicate knowledge or
intelligence, are 'information', which you said... oh, by now you should
be getting the gist of this.

DD

Richard

unread,
Jun 19, 2004, 2:49:46 AM6/19/04
to
robert.d...@wagner.net (Robert Wagner) wrote

> But it has, at least once. When Structured Programming appeared in the late
> '60s, we already had a substantial body of work based on GO TO. Had this forum
> existed then, I can picture heated debates between the Old Guard defending GO TO
> and bright-eyed 'progressives' decrying GO TO. For once, the good guys won,
> although we still see backguard pockets of resistance some 35 years later.

There is nothing in 'structured programming' that prohibits the use of
GO TO, though it may restrict the scope of its use.

Personally I find that I never need GO TO and have a style in which it
can not be useful.



> What happened to that spirit of improvement? OO Cobol is roughly comparable to
> Structured Programming back then. Why has it been ignored by the Cobol
> community? Because we're now aged 50-60 rather than 20-30? Or is it because
> mainframe shops have Programming Standards prohibiting progress? (pardon
> alliteration)

No. That is not the case. Much of the OO features in C++, for
example, are to solve the problems of the C language. In many cases
Cobol never had those problems. Now OO does have some really useful
functionality, in many cases the types of applications that Cobol is
commonly used for does not need this functionality. In other cases,
such as in your demonstration, the OO is not only inappropriate but is
far slower when compared to conventional solutions.

If you had learnt other languages well enough then you would have seen
where the OO solutions were required and could evaluate whether these
could be applied to Cobol.

> I don't think pointers make Cobol C-like; I think they make it equally capable.

One of the reasons that C++ of the 80s is a step up from C is that it
replaced pointers with objects. Memory management was contained
within the objects. The reason that Java of the 90s is a step up
from C++ is that the objects themselves are garbage collected. These
two steps removed all the manual grubbiness from pointers that were
the bane of C.

Cobol never had this pointer problem because the applications
generally did not require them. C used them to build trees, lists and
other complex structures. Cobol just put this data into files and
arrays.

Introducing pointers to Cobol in the way you want them to be used just
takes the language back to the C of the 70s. There are reasons for
wanting pointers, such as interacting with the OS, but these should be
as restrained as possible. They are not an 'advanced feature', they
are taught in a 'C advanced course', because the programmer needs to
be better than a beginner.

> Before compilers 'extended the Standard' to support pointers, we did it with
> calls to assembly language programs that modified 'BLL cells'. Pointers are an
> essential tool. Their absence in Java and C# is a serious limitation to those
> cultures.

You simply show that you never went through the learning process that
led to the reason why they are not in Java or C#, and what has
replaced the need for them.

While trivial programs, such as your demos, may make pointer
management seem easy this is not the case in any substantial program.
C++ programmers who wrote large C applications with pointers know why
C++ introduced objects. Java programmers who did large systems in C++
know why garbage collection was added and pointers were removed.

You obviously did not go through that and so promote starting at step
1 in the 70s.

> Resisting progress is one thing, arguably good; ignoring and rejecting it is
> Bad. Cobol's strength doesn't come from immutability, it comes from
> extensibility. OO Cobol is a good demonstration of the language's vibrancy ..
> and its adherents' resistance to progress.

Pointers are _not_ progress. Your demo of doing anappropriate things
with collection classes and then concluding they are slow and poor is
not progress. If you want progress then do something _better_.

> I agree -- diletantes will not stick with Cobol. Good riddance.

So why do you care what they say about Cobol ?

Robert Wagner

unread,
Jun 19, 2004, 4:59:39 AM6/19/04
to
"Chuck Stevens" <charles...@unisys.com> wrote:

In the end, the only real protection is that provided by hardware. Descriptors
can be forged -- copied from a parent program's stack.

>> I concur that it wouldn't be an improvement for general applications
>programs,
>> but contend it would be for systems software charged with diagnosing a
>failure.
>
>Well, yeah ... the MCP, which has access to the entire system because it has
>special privileges, decodes this information on behalf of the diagnostic
>software. The problem with that is ... ?

Third-party software might be superior. IBM mainframes have a long history of
third-party abend analyzers that work better than IBM's. In my limited
experience with Burroughs medium systems (B3500/4700), I found it necessary to
improve the MCP's communication module to make the first Telechek system work,
and to rewrite the print spooler from scratch to improve its functionality. Many
shops switched to my print spooler. A cursory Web search shows third-party
performance monitors and memory optimizers for the current Unisys MCP.

BMC, the first billion dollar software company, was founded in the late '60s to
provide services MUCH better than IBM's offerings. I recall meeting with them
and being blown away by their technical skill.

Third-party software must sometimes resort to 'hacking' because the hardware
manufacturer arrogantly assumes its way is the only way.

Robert Wagner

unread,
Jun 19, 2004, 4:59:40 AM6/19/04
to
"Chuck Stevens" <charles...@unisys.com> wrote:

>
>"Robert Wagner" <robert.d...@wagner.net> wrote in message
>news:40d0ddc7...@news.optonline.net...

>> If dataname is the same on the next CALL, as it is 99% of the time, the


>call
>> would be faster than the first.
>
>Where on earth did you get *that* statistic? The whole point of CALL
><dataname> is that the programmer *doesn't* know what the name of the called
>program is going to be until he gets to the CALL statement! If 99% of the
>time it's the same, why not use CALL <literal>?

Before compiler options such as DYNAM, we were forced to write CALL <dataname>
to get dynamic (late) binding. That was the case on IBM mainframes for many
years.

>I'm not sure the standard cares, but I would suggest that the Unisys MCP
>implementation, which requires no post-compile pre-execution steps and uses
>dynamic links, matches both the spirit and the letter of the ANSI spec in
>this fashion. A compiled COBOL74 program is ready to execute in our
>environment as soon as the compiler's locked the file in the disk directory,
>whether that execution is "manual" or as a called program in a COBOL74 run
>unit. That's the convention on Unisys MCP systems, where a "linking"
>process is very much the exception and is always carefully considered in
>application design. On systems where a "link" step is usual or even
>mandatory, it wouldn't be surprising for ANSI IPC handling to include such a
>step, but that's not the case on Unisys MCP systems, and a bind (or rebind)
>during every compilation would be regarded by most Unisys MCP users as
>extremely tedious and contrary to their expectations.

I'm pleased to read that. Late binding is also the norm on Unix and Windows.

>The distinction "early" vs. "late" may apply to Unix. It may apply to IBM.
>But it is simply not meaningful in the Unisys MCP environment when it comes
>to a *single* CALL mechanism. If you want called routines to be linked
>*before* execution -- in which case they form a single object code file with
>the caller -- then you specify USE EXTERNAL and CALL <section-name>. That,
>in MCP terminology, is called "using bound procedures". Many do that. If
>you want the ability to replace the called program on the fly, then you can
>use ANSI IPC syntax or minor extensions to it. That, in MCP terminology, is
>called "using library calls".

Unix terminology is the same. The files are even named 'LIBxxx.so'.

Robert Wagner

unread,
Jun 19, 2004, 4:59:40 AM6/19/04
to
"Chuck Stevens" <charles...@unisys.com> wrote:

>
>"Robert Wagner" <robert.d...@wagner.net> wrote in message
>news:40d0eaff...@news.optonline.net...
>
>> Clear as mud. Just tell me the name of the failed program and line number
>on
>> which it failed. Given that, I can figure out why it failed. Do I ask too
>much?
>
>Unisys MCP COBOLs don't deal in *line* numbers, they deal in *sequence*
>numbers (remember columns 1-6?).

Major YUCK. Even the retrograde Cobol I support has given up on columns 1-6.
They use it for 'version control', with values like "rw0618".

>Given that, for a system consisting exclusively of separately-compiled COBOL
>programs, the program dump provides the object code file name of the
>compilation unit and the sequence number and actual object code instruction
>address of the failure for each level in the PERFORM and CALL stack history.

Good. That's what we want.

>For a program that's nested, the sequence numbers identify the location of
>the failure, the call history within the compilation unit, the object code
>file name of the compilation unit, and the actual object code instruction
>address for of the failure for each level in the PERFORM and CALL stack
>history.
>
>The sequence number history of any failure is also by default provided in
>the abnormal-termination message, though you may actually have to glance at
>the program dump to find out which sequence number goes with which program.
>
>Have you *demonstrated* that you need more information than the MCP has
>already provided *you*? Or is it just "I want to do it *my* way, not the
>way the system allows me to do it!"?

Policy determines the fate of systems and institutions. Politics determines the
fate of individuals. Although both are based on the same Greek root word "pol",
meaning people, they refer to different mental processes. Policy is rational
whereas politics is emotional.

By emphasizing "you", you're trying to redirect the discussion into a political
vein. I claim no special credentials nor authority on Cobol. I'm just a code
cranker.

It is loading more messages.
0 new messages