Advanced Language FeaturesNext

Chapter 1: Writing Programs

The information in this chapter is designed to help you produce programs that run as efficiently as possible. It includes information on the following:

The information in this chapter applies to programs compiled to native code not intermediate code unless otherwise stated.

1.1 Performance Programming

This section gives some guidelines which, if followed, enable your Server Express system to optimize fully the native code produced for your programs. This results in smaller and faster applications. Do remember that these are only guidelines; programs that do not conform to these guidelines still run correctly, just less efficiently.

Programs using Server Express can be moved to other systems provided certain portability rules are followed.

1.1.1 Data Types

Using the correct data-type is important to get the greatest efficiency from operations, particularly arithmetic operations. For details of how each data-type is stored refer to your Language Reference.

1.1.2 Procedure Division Considerations

This section identifies items in the Procedure Division which affect the size and performance of your program, and suggests the most efficient ways of using them.

As a general rule, the simpler the operation, the faster it executes and the smaller the compiled code. To get the best performance it is often better to use a number of simple operations rather than one complex operation. The following are general guidelines that result in the fastest and smallest possible code.

1.1.2.1 Arithmetic Statements

To get the best performance from arithmetic statements always use the simplest forms.

1.1.2.2 Alphanumeric Data Manipulation

The following list suggests the most efficient ways of using alphanumeric data manipulation:

1.1.2.3 Table Handling

The following list suggests the most efficient ways of table handling:

1.1.2.4 Conditional Statements

The following list suggests the most efficient ways of using conditional statements:

1.1.2.5 Logical Operations

A number of COBOL System Library Routines (call-by-name) are available to perform bit-wise logical operations on data items. These are described in the chapter Advanced Language Features. They perform operations such as bit-wise AND, OR and XOR.

The Compiler recognizes calls to these routines and, if possible, optimizes them to produce in-line code rather than calls to the run-time system. The calls are optimized if the length is specified as a literal. In-line code is native code which performs the function directly without making any calls. The alternative is a call to a generic run-time routine which must allow for many cases.

The calls are optimized if the length is specified as a literal.

Logical AND and logical OR operations can also be carried out using the VALUE clause. See your Language Reference for details.

1.1.2.6 The PERFORM Statement

Using PERFORM is generally very efficient, and is a very good way of keeping the size of your program down as well as giving it an easy-to-maintain structure. The following rules enable you to use it in the most efficient ways.

1.1.2.7 CALL Statements

The following list suggests the most efficient ways of using alphanumeric CALL statements:

1.1.2.8 Parameters

Avoid making many references to linkage items. These include items defined in the Linkage Section, items set to CBL_ALLOC_MEM allocated memory, and items defined as EXTERNAL .

Accessing linkage items is always slower than accessing Working-Storage Section items. If a Linkage Section item is used frequently, it is faster to move it into a Working-Storage Section item when the program is entered and move it back to the Linkage Section if necessary before exiting to the calling program. The Working-Storage Section item should then be accessed throughout the program rather than the item in the Linkage Section.

1.1.2.9 Sorting Files

If you use input and output procedures with a file sort in your program it is important that you write them efficiently as they are executed once for each record you are sorting. Inefficient input and output procedures can make the sort process appear to be very slow.

1.1.3 Compiler Directives

A number of Compiler directives can be used to make the native code for a program better optimized. Some of these directives must be used with care; ensure that the behavior you get with them is acceptable.

In general, always use the following directives when compiling your programs to native code:

NOALTER
ALIGN"4" (32-bit systems)
ALIGN"8" (64-bit systems)
COMP
NOBOUND
NOCHECK
NOCHECKDIV
NONESTCALL
NOODOSLIDE
NOQUAL
NOSEG
NOTRUNC

Other suggestions (to help prevent inefficient coding)

REMOVE "ROUNDED"
REMOVE "ERROR"
REMOVE "INITIALIZE"
REMOVE "CORRESPONDING"
REMOVE "THRU"
REMOVE "THROUGH"

By removing these reserved words you prevent the possibility that code using these inefficient constructs will be added to the program.

1.1.3.1 Using Directives to Optimize for Speed

There are many directives you can use to optimize for speed. In some cases, the defaults for Compiler directives are the ones that provide speed optimization. This section points out directives that need to be changed from their default values to provide for speed optimization.

ALTER Directive

For efficiency reasons, you should not use ALTER statements in programs. It is recommended that you avoid them altogether, and compile with NOALTER, to prevent the Compiler from having to produce code to look for them.

BOUND Directive

The BOUND directive does boundary checking on table items.

Your applications can be made faster (and smaller) by compiling with NOBOUND. Otherwise, the Compiler inserts extra code to do boundary checking on all references to table items.

During testing, you should use the BOUND directive until you are satisfied that your program is not referencing data beyond your table limits. For production, NOBOUND gives you the desired efficiency.

BOUNDOPT Directive

The BOUNDOPT directive can be used to optimize your code if the following apply:

When BOUNDOPT is specified, digits in a USAGE DISPLAY subscript above the size of the table are ignored. For example, a PIC 9(3) subscript would be treated as PIC 9(2) for a table with less than 100 entries.

We recommend that you do not use USAGE DISPLAY subscripts.

COMP Directive

The COMP directive prevents code checking for numeric overflow. This produces highly compact and efficient code.

COMP changes the behavior of arithmetic on data items defined as USAGE COMP. It produces more efficient code, but the behavior does not conform to the ANSI standard.

If used with the proper care, COMP can improve the speed of your programs.

NESTCALL Directive

The NESTCALL directive enables nested programs to appear in your program. If you know you have no nested calls in your program, specifying NONESTCALL enables the Compiler to generate slightly more efficient code.

TRUNC Directive

The TRUNC directive causes the Compiler to create code to determine whether USAGE COMP data items need to be truncated or not.

If you are certain that you do not need truncation of USAGE COMP data items, NOTRUNC causes the creation of more efficient code.

1.1.3.2 Using Directives to Optimize for Size

There are many directives you can use to optimize for size. In some cases, the defaults for Compiler directives are the choices that provide size optimization. This section points out directives that need to be changed from their default values to provide for size optimization.

ALIGN Directive

This directive specifies the boundary on which level-01 and level-77 items start. This boundary should always be a power of two, such as two, four or eight. For 32-bit COBOL systems use a minimum of ALIGN"4". Use ALIGN"8" if you are using a 64-bit operating system. Higher powers of two retain efficiency, but increase the amount of unused space between data records.

1.2 Avoiding Data Inaccuracies

You might get unexpected results from arithmetical operations involving floating point calculations, as COBOL does not by default round numbers. For example, say WS02 is defined as a COMP-2 data item, and the following operations are performed:

accept ws02
compute ws02 = ws01
display ws01

If you enter a value of 2.3 when requested by the program, the value displayed will be 2.29.

If you want values to be rounded you must specify the ROUNDED clause. The example above would be rewritten as:

accept ws02
compute ws02 rounded = ws01
display ws01

You can specify that all data-items in a program are rounded or truncated using the Compiler directive FP-ROUNDING. See the chapter Directives for Compiler in your Server Express User Guide for more details of this directive.

1.3 Implementation of Floating-point on 32-bit and 64-bit COBOL Systems

Server Express provides IEEE floating-point support. The following sections describe the range of values and the accuracy available using floating-point support.

1.3.1 Range

The range of values available with each of the two COBOL binary floating-point data types is as follows:

COMP-1 from 8.43E-37 through 3.37E38
-8.43E-37 through -3.37E38
COMP-2 from 4.19E-307 through 1.67E308
-4.19E-307 through -1.67E308

Note: Although the underlying floating point support used by this COBOL system does support the above ranges, this COBOL system only supports 2 digit exponents.


1.3.2 Accuracy

The following table shows the relationship between storage size and significance.

Type
Size
Significant digits
COMP-1 4 bytes 6-7
COMP-2 8 bytes 15-16

1.3.3 External Items and Literals

The compiler validates floating point literals to ensure their values are compatible with the mainframe environment. Literal values that do not lie within the following range will cause a compile-time error:

from 0.54 E -78 through 0.72 E +76
and from -0.54 E -78 through -0.72 E +76

1.3.4 Inaccuracies in Floating-point

All IEEE format binary floating-point values consist of:

If the value is non-zero, the exponent has a constant subtracted to give the starting value of the mantissa. Thus, the value of a double precision (COMP-2) item in terms of its mantissa (m) would be:

1*(2**m) + mb0*(2**(m-1)) + mb1*(2**(m-2)) + mb2*(2**(m-3)) + ... + 1*(2**(m-52))

where the mantissa bit (in this example, mb0 through mb51) can be 0 or 1. For COMP-1 (single precision) fields, this becomes an issue when the difference between the maximum and the minimum powers of 2 is greater than 23; for COMP-2 fields, the issue might arise when the difference between the maximum and minimum powers of 2 is greater than 52.

For example, if a COMP-2 field is expressed with one mantissa bit multiplied by 2**56, and another mantissa bit multiplied by 2**2, then the value in the field would need to be approximated, because 56 - 2 = 54, which is greater than 52. This would be true in any floating point implementation on any hardware platform. Additionally, the internal storage format of floating point numbers can differ from operating system to operating system; see page 2-40 of your Language Reference manual. These discrepancies can occur because of variations in the internal storage of floating point numbers between operating systems.

Binary floating point can only represent powers of 2 (both positive and negative), and combinations of these powers of 2. For example, a fractional decimal number is represented by adding together the combination of values from the sequence 1/2, 1/4, 1/8, 1/16, 1/32, and so on, that comes closest to the required value. Thus, a value such as 0.625 (i.e., 1/2 + 1/8) can be represented exactly, whereas other values are represented by an approximation (which might be slightly above or slightly below the true value). Similarly, an integer is represented by adding together the combination of values from the sequence 1, 2, 4, 8, 16, and so on, that comes closest to the required value. Thus, a value such as 625 (which can be made up from 1 + 16 + 32 + 64 + 512) can be represented exactly, whereas other values are represented by an approximation.

1.4 Handling Large Programs

The Server Express system enables you to execute statically linked or dynamically loaded code. Statically linked code is embedded within the executable file. Dynamically loadable code is a COBOL callable shared object, or .int or .gnt file that is loaded and run only when the file is called. The code is held in a separate file to the executable file. The dynamic loader loads COBOL program overlays as needed.

When designing a COBOL application program that is to be dynamically loadable, you want it to make efficient use of the available memory. It is possible, using this COBOL system, to create and run programs that use more memory than is physically present in your computer. You can do this by separating the program into smaller programs and using the COBOL call mechanism (see the section Inter-program Communication (CALL) later in this chapter).

The run-time system also provides another method for creating and running programs that use more memory than is physically present in your computer. It enables you to segment one large COBOL program so that it holds on disk the code that is not being used.

1.4.1 Inter-program Communication (CALL)

This section looks at the inter-program communication (call) mechanism for creating large applications but avoiding large programs.

The COBOL system enables you to design applications as separate programs at source level. Each program can then be called dynamically from the main application program without first having to be linked dynamically with the other programs. Figure 1-3 shows an example of an application divided up in this way.


Figure 1-1: Application Divided Using CALL

The main program A, which is permanently resident in memory, calls B, C, or H, which are programs within the same suite. These programs call other specific functions as follows:

B calls D, E and F
C calls X, Y, Z, L and K
H calls K
K calls M, N and O.

Because the functions B, C and H are standalone they do not need to be permanently resident in memory together. You can call them as they are needed, using the same physical memory when they are called. The same applies to the lower functions at their level in the tree structure.

In the figure, you would have to plan the use of CALL and CANCEL operations so that a frequently called subprogram such as K would be kept in memory to avoid load time. On the other hand, because it is called by C or H, it cannot be initially called without C or H in memory; that is, the largest of C or H should call K initially so as to allow space. It is important also to avoid overflow of programs. At the level of X, Y and Z, the order in which they are loaded does not matter because they do not make calls at a lower level.

It is advantageous to leave called programs in memory if they open files, to avoid having to reopen them on every call. The EXIT statement leaves files open in memory. The CANCEL statement closes the files and releases the memory that the canceled program occupies, provided all other programs in the executable file have been canceled or never called.

If you use a tree structure of called, independent programs as shown earlier, each program can call the next dynamically by using the technique shown in the following sample coding:

 working-storage section.
 01 next-prog      pic x(20) value spaces.
 01 current-prog     pic x(20) value "rstprg".

 procedure division.
 loop.
     call current-prog using next-prog
     cancel current-prog
     if next-prog = spaces
         stop run
     end-if
     move next-prog to current-prog
     move spaces to next-prog
     go to loop.

The programs to be run can then specify their successors as follows:

      . . .
      . . .
 linkage-section.
 01 next-prog pic x(20).
      . . .
      . . .
 procedure division using next-prog.
      . . .
      . . .
     move "follow" to next-prog.
     exit program.

In this way, each independent segment or subprogram cancels itself and changes the name in the CALL statement to call the next one with the USING phrase.

1.4.1.1 Call Requirements

Having decided to use the call mechanism for your application, the following sections look at some of the practical aspects of creating such applications.

The total number of programs which can be loaded in memory as the result of a call is not constant. The number depends on the amount of available memory in your computer and the size of the program being called.

Dynamically called programs have an advantage over programs that have been linked into a single executable file, in that dynamically called programs have their memory freed when they are canceled while the latter do not.

1.4.1.2 Public Symbols and Your Program-Id

If a program is called and the program is dynamically loaded, the filename is used to identify it. If the program is statically linked then the Program-Id paragraph can be used. See the section Calling COBOL Subprograms for more details.

You can avoid many "program not found" errors by always using the filename without extensions as the program-name in the Program-Id paragraph. This enables flexibility in constructing your executable programs with statically or dynamically called programs.

For details on the Program-ID paragraph, see your Language Reference.

1.5 Calling Subprograms

This section looks in more detail at how to call subprograms. It provides information on writing subprograms and passing parameters between them.

You can write subprograms or your main programs in the COBOL language or in some other language, such as C. You can mix these subprograms freely in an application. However, before you call a non-COBOL subprogram from a COBOL program, you must link it to either the dynamic loader run-time support module or to your statically or dynamically linked COBOL application.

1.5.1 Calling COBOL Subprograms

A COBOL subprogram can be linked, or it can also be dynamically loaded at run time.

A linked program is an executable object module, while a dynamically loadable module is a COBOL intermediate code file (.int file), COBOL generated code file (.gnt file), or a COBOL callable shared object.

A COBOL program can call a COBOL subprogram by using one of the following formats of the CALL statement:

CALL "literal" USING ...

or:

CALL data-name USING ...

For any COBOL programs, the literal string or the contents of the alphanumeric data item must represent the Program-ID, the entry point name, or the basename of the source file (that is, the filename without any extension). The path and filename for a module can also be specified when referencing a COBOL program, but we do not recommend you do this, as unexpected results can occur where the referenced module exists in more than one file, or type of format, or if the application is ported to other environments. For statically linked modules, the native code generator converts calls with literal strings to subroutine calls which refer to external symbols. The Micro Focus COBOL system automatically creates a routine to define the symbol and to load the associated file if it is entered at run time.


Note: Programs that are called at link time must have names that the system assembler and linker can accept; that is, they must not contain characters other than 0-9, A-Z, a-z, underscore (_), or hyphen (-). You must correct any entry point names that use characters other than these so that they are acceptable to the system assembler and linker.


1.5.1.1 Calling Linked Programs

Use a CALL literal statement to call a linked program directly. If the program is not found a run-time system error is displayed unless the dynamic loader is present, in which case it will attempt to find a dynamically loadable version of the program.

1.5.1.2 Calling Dynamically Loadable Programs

Use either a CALL literal statement, or a CALL data-name statement, to call a dynamically loadable program, and make the dynamic loader run-time support module search for the called program.

You might need to load the dynamic loader using the cob utility.See the chapter COBOL System Interface (cob) in your Server Express User Guide for more details of this directive.

The dynamic loader run-time support module follows this search order to find the named file:

  1. The entry points of all loaded programs

  2. The disk in order to find a suitable file from which the program could be loaded

If the dynamic loader run-time support module has to search for a file on disk and no path-name has been specified on the call, the search order followed is:

  1. The directory from which the calling program was loaded

  2. The directories specified by the COBDIR environment variable. You can set COBDIR to a value of the form:
    [;] path-name [;path-name] ...

    For example:

    set COBDIR=d:/cobol/lbr;d:/cobol/exedll

    If you include the optional semicolon (;) at the beginning of the string, the dynamic loader run-time support module assumes the current directory is the first one to be searched

If you specify a directory path on the call, the dynamic loader support module searches for the file only in the named directory.

If you specify a file extension, the dynamic loader run-time support module searches only for a file with a matching extension. However, we recommend that you do not include an explicit extension in the filenames you specify to the CALL statement. If you specify a file without an extension, the dynamic loader run-time support module adds the extension .so to the basename of the file, and searches the disk for the corresponding callable shared object file. If it cannot find the callable shared object the dynamic loader run-time support module adds the extension .int to the basename of the file, and searches the disk for the corresponding intermediate code file. If it cannot find the .int file, the dynamic loader run-time support module adds the extension .gnt to the basename of the file, and searches for the corresponding .gnt file.

The dynamic loader run-time support module always assumes that the first matching program name which it finds is the program you require to CALL.

If no matching program is found a run-time error occurs.

Note that if the first character of a filename which is to be dynamically loaded at run time is the dollar sign ($), the first element of the filename is checked for filename mapping. The first element of the filename consists of all the characters before the first slash character (/).

See your File Handling for details. For example, if the statement:

   CALL "$MYLIB/A"

is found in the source program, the file A is loaded from the path as defined by the MYLIB environment variable at run time.

1.5.2 Calling Non-COBOL Subprograms

You can access non-COBOL subprograms using the standard COBOL CALL ... USING statement. The address of each USING BY REFERENCE or USING BY CONTENT parameter is passed to the argument in the non-COBOL subprogram which has the same ordinal position in the formal parameter declarations. You must thus ensure all formal parameter declarations are pointers.

Note that if you use the CALL...USING BY VALUE form of the CALL...USING statement, the USING parameter is not passed BY VALUE if it is larger than four bytes long. If it is larger than this, it can be passed BY REFERENCE, but no warning is output to inform you of this. If you specify a numeric literal with a CALL...USING BY VALUE statement, it is passed BY VALUE as though it were a four-byte COMP-5 item; that is, it appears in machine-order as a data item and not as a pointer to that data item. If you specify a data item with a CALL...USING BY VALUE statement it must be defined as COMP-5.

You might need to specify a particular calling convention when interfacing to non-COBOL programs - see the chapter The COBOL Interfacing Environment for more information.

The following example shows how C functions can be accessed from a COBOL program

Example - Accessing C functions from a COBOL program:
$set rtncode-size"4"

 working-storage section.
 01 str.
   03 str-text  pic x(10).
   03 filler   pic x value x"00". 

* Null terminate string for C function
 01 counter pic 9(8) comp-5 value zero.

 procedure division.
 call-c section.

   call "cfunc" using str, counter
   if return-code not = zero
* RETURN-CODE set from return () in C
         display "ERROR"
     else
         display "OK"
     end-if
     stop run.

------------------------------------------------
cfunc  (st, c)
char  *st;
int   *c;
{
   ...
   return(0);
} 

When you use the CALL statement from within a COBOL program to access a non-COBOL module as described above, you must ensure that the COBOL run environment is not accidentally damaged. This means you must ensure that:

The CANCEL statement has no effect when it references a non-COBOL program .

1.5.2.1 RTS Errors 114 and 115

The Server Express system traps unexpected signals and returns run-time system errors:

114 Attempt to access item beyond bounds of memory
115 Unexpected signal

Where C and COBOL modules are linked, these error messages are usually due to an error in the C code which causes a hardware interrupt for such conditions as segmentation violation. If you do receive these run-time system errors, carefully check the C source routines using the system debugger, paying particular attention to the format and byte ordering of parameters passed between the COBOL and C modules.

1.6 Program Entry Points

COBOL programs can contain ENTRY statements. An ENTRY statement identifies a place where execution can begin as an alternative to the Procedure Division if a calling program so specifies.

COBOL fully supports entry points, but the dynamic call loader presents a potential problem. Because the run-time system typically defaults to looking for called programs dynamically, there is no way for the run-time system to locate a particular entry point embedded in a program on disk. When you execute a call statement like:

call "abc" using ...

the run-time system first looks for a program or entry point called abc in all of the programs and libraries that have already been loaded. If it does not find the program, the run-time system then looks for a file called abc.ext where .ext is an executable file formats. For details of executable file types see the section Executable File Types in the chapter Packaging Applications in your Server Express User Guide.

If abc represents the name of an entry point contained in another program, the run-time system cannot locate the file on disk, and a "program not found" message is issued. The run-time system does not scan through every individual executable file on disk to locate an entry point.

Therefore, you must load the program containing the called entry point into the run-time system.

One technique that you can use to do this is to create a .lbr file that contains any programs containing entry points that need to be preloaded. You can create the .lbr file (library file), using the Library facility. Once the .lbr file is created, you can issue a call to the .lbr file.


Note: When you call an .lbr file, the run-time system does not load every program in the .lbr into the run-time system. Instead, the run-time system registers the existence of all programs and entry points contained in the called .lbr file, for future reference. Later when one of these programs contained in the .lbr is called, the run-time system notes that it is contained in the .lbr and loads it at that point.


Once a program that contains the entry points is loaded into the run-time system, all entry points contained in the program are identified to the run-time system and are available to be called by any program loaded later. This means that if you need to call entry points in a particular program from another program, you must ensure that the program is loaded first, so the run-time system can register these entry points.

1.7 Passing the Command Line

This section describes how you call a program and pass the command line to the main program as a parameter. The main program in a run unit is the first program within it; that is, the program which is called directly by the COBOL system.

As the maximum size, form and contents of the command line vary between operating systems, these issues need to be considered if you want to port your application between environments. For example, to ensure portability, a maximum command line size of 128 characters might be appropriate rather than the system limit. Similarly, only alphabetic and numeric characters with the equals sign (=) and space characters should be used for entering the command line for a program if you want to guarantee portability.

The command line can be accessed from:

1.8 Program Calling Conventions

The standard COBOL calling convention is:

call progname using ...

or:

call "progname" using ...

where progname (without quotation marks) is a data item that contains a valid program-name, and "progname" (with quotation marks) is the actual name of a valid program.

1.8.1 Program Names

A program-name is a character string representing the program or subprogram to be called. In the run-time system, this name is treated as an implicit program-name; that is, there is no filename extension in the program-name.

This means the actual executable file being called might be in any of the following supported executable formats:

When progname.lbr is found, the run-time system opens the .lbr file and locates and loads an executable file with the same program-name, for example progname.gnt, progname.int, or progname (no extension) from the .lbr file.

An explicit program-name can be specified in the call statement as well:

call "progname.gnt" using ....

This forces the run-time system to look for the exact filename specified, in this case progname.gnt. If the exact program-name is not located a "program not found" error message is issued.

1.9 Program Management

Once started, the run-time system sets up a 32-bit addressing virtual storage environment in which it loads and manages all called subprograms. When the run-time system locates and loads a called program, it assigns a unique run-time system identifier to the program. (This identifier is used internally in the run-time system.) The run-time system allocates memory (both real and virtual) for the program, and can swap portions of it out to disk as needed.

The run-time system records the actual location, drive and path-name as well. Once loaded into the run-time system, the run-time system uses the same copy of the program unless it is canceled and recalled.

1.10 Called Program Search Conventions

Whenever a COBOL program running under the run-time system issues a call to a subprogram, the run-time system goes through the following steps:

  1. Locate and open the program file.

  2. Load the program file into the run-time system.

  3. Close the program file.

As described above, the run-time system can search for multiple executable files, and can search for these program files in more than one directory.


Note: The search sequences described below apply to executable files (programs). It does not apply to other file types, for example data files and COBOL source files.

You do not need to be concerned about search conventions if you only have one executable version of your program on disk. This discussion only applies if you have multiple executable files available.


Whenever a COBOL program issues an explicit call to a subprogram, for example:

call "myprog.gnt" using ...

the run-time system searches for a file with the specified extension.

In this case, the run-time system searches for myprog.gnt. It does not search for other valid executable formats with the same program-name but different extensions.

When a program issues an implicit call, that is, a call to a program-name without specifying a file extension, the run-time system searches for the called program in the order listed below.

When a program issues a call like:

call "proga" using ...

the run-time system searches through the following sequence looking for proga:

1 proga.so
2 proga.gnt
3 proga.int
4 proga.lbr The run-time system opens this .lbr file and searches it for an executable name
5 proga No extension

If none of the above are found, the run-time system issues the message, "program not found".

You can change the order in which the run-time system searches for files by setting the I1 run-time switch. This causes the run-time system to search for files in the order :

1 proga.so
2 proga.int
3 proga.gnt
4. proga.lbr

This is useful for testing when you are typically compiling only to intermediate (.int) code.

When the run-time system finds and loads a program, it records the location (drive and path) where the program was first found. If the program issues a later call to another program, the run-time system does not look in the current directory for the new program being called. Instead, it defaults back to the same directory where the calling program was first found.

If the run-time system cannot find the called program in the same directory that the calling program is in, the run-time system begins its standard search sequence to try to locate the called program. This technique, known as inheritance, is the default behavior for the run-time system.

1.10.1 Searching Through Multiple Directories

It is also important to understand the way the run-time system searches for various executable files through the multiple directories that can be set in the COBDIR environment variable. For example, if your program issues a call to a program like:

call "myprog" using ...

the run-time system initially searches its active directory to see if myprog has already been loaded (and not subsequently canceled).

If it has been loaded, the run-time system passes control to myprog. It does not refresh the program's Data Division unless:


Note: You should be aware of the impact of inheritance on the run-time system search sequence. If you have the same program-name in more than one directory, you can access the wrong version.



Copyright © 1999 MERANT International Limited. All rights reserved.
This document and the proprietary marks and names used herein are protected by international law.
Advanced Language FeaturesNext