CALL Statement

The CALL statement causes control to be transferred to another program. For a discussion of how the runtime handles program calls, see Calling Subprograms. See Working with Windows Technologies and Working with C and C++ Programs for information about calling subroutines in DLLs and UNIX shared libraries.

Format 1

CALL [IN THREAD] program-name

 [ HANDLE IN handle-1 ]

 [ USING { [ BY {REFERENCE} ] {parameter} size-phrase ...} ...]
                {CONTENT  }   {OMITTED  }
                {VALUE    }   {NULL     }

 [ {RETURNING} INTO return-val ]
   {GIVING   }

 [ ON     {EXCEPTION} statement-1 ]
          {OVERFLOW }

 [ NOT ON {EXCEPTION} statement-2 ]
          {OVERFLOW }

 [ END-CALL ]

where size-phrase is:

[WITH MEMORY SIZE {= } memory-size]
                  {IS}

Format 2

CALL RUN program-name

 [ USING {parameter} ... ]

 [ ON  {EXCEPTION} statement-1 ]
       {OVERFLOW }
 [ NOT ON  {EXCEPTION} statement-2 ]
           {OVERFLOW }

 [ END-CALL ]

Format 3

CALL PROGRAM program-name

 [ USING {parameter} ... ]

 [ ON  {EXCEPTION} statement-1 ]
       {OVERFLOW }

 [ END-CALL ]

Format 4 (HP COBOL)

CALL { identifier-1            } [ USING { \\             } ... ]
     { [ INTRINSIC ] literal-1 }         { @identifier-2  }
                                         { identifier-2   }
                                         { literal-2      }
                                         { \identifier-2\ }
                                         { \literal-2\    }

     [ GIVING identifier-3 ]

     [ ON {EXCEPTION} statement-1 ]
          {OVERFLOW )

     [ NOT ON {EXCEPTION} statement-2 ]
              {OVERFLOW )

     [ END-CALL ] ]

Syntax Rules

Note: For Syntax Rules and General Rules specific to Format 4, see HP COBOL Conversions in Transitioning to ACUCOBOL-GT.
  1. program-name is a nonnumeric literal or an alphanumeric data item.
  2. handle-1 must be a USAGE HANDLE or HANDLE OF THREAD data item.
  3. The NULL and OMITTED options are synonymous.
  4. memory-size is a numeric literal or data item.
  5. parameter is any non-level 88 data item or a literal. It may be subscripted and reference modified. It may be the SELECT name of an open COBOL file.
  6. statement-1 and statement-2 are imperative statements.
  7. EXCEPTION and OVERFLOW are equivalent.
  8. The NOT EXCEPTION phrase may not be used when the PROGRAM option is used.
  9. return-val must specify a numeric data item.
  10. RETURNING and GIVING are synonymous.

General Rules

  1. program-name specifies the name of the called program. The exact procedure for resolving this name into the name of a program to call is described in File Name Interpretation.
  2. The THREAD option starts a new thread before calling the target program. The called program executes in the new thread. The calling program continues to execute in parallel. When the called program exits, its thread is terminated.
  3. The HANDLE phrase stores the ID of the thread in handle-1 immediately after the new thread starts. This occurs before the USING parameters are evaluated, so that it is possible to pass handle-1 to the called program.
  4. The parameters' order of appearance in the USING phrases of the CALL verb, and the called program's Procedure Division header, determine the correspondence between the data names used in the called and calling programs. This correspondence is established by position, not by name.
  5. The SIZE phrase is used when the parameter in the USING phrase is a memory address (pointer to memory) and you need to specify the size of the piece of memory that is located at that address. The SIZE phrase supports the calling of DLLs on the display host by thin client applications..
  6. The BY phrase controls how parameters are passed to the called program. The default method is BY REFERENCE. This method causes the address of the data item to be passed to the receiving program. This is the only method of passing data available in versions of ACUCOBOL-GT prior to 2.0.

    The BY CONTENT phrase is similar to BY REFERENCE, except that the address of a copy of the data item is sent. This has the effect that any changes made to the parameter in the called program are not seen by the caller. Starting with Version 2.0, literals passed as parameters are automatically passed BY CONTENT.

    The BY VALUE method causes the contents of the data item to be passed to the receiving program (the actual data, not its address). This may not be specified if the receiving program is a COBOL program (results are undefined in this case). This method is typically used to pass numeric data to C subprograms. For optimal portability we recommend that parameters being passed by this method be level 01 or 77 items described as SIGNED-INT, UNSIGNED-INT, SIGNED-SHORT, UNSIGNED-SHORT, SIGNED-LONG, UNSIGNED-LONG, or POINTER.

    When the name of an open COBOL file is given as a parameter, the operating system's file handle is passed. One possible reason for doing this is to call an operating system function that allows the file to retrieve some information that is not available through COBOL. Several special rules apply to this usage. See rules 30 through 35 below.

  7. The NULL and OMITTED options are synonymous. They allow you to skip a parameter in a USING phrase. The corresponding parameter in the called program must not be referenced. If the called program is a C program, then a NULL value is passed to the corresponding parameter.
  8. Index names referred to in the Linkage Section of the called program do not correspond to any index names in the calling program. Index data items are always stored in the local memory of their programs.
  9. If the called program does not have the INITIAL attribute, then it is in its initial state the first time it is called, and the first time it is called after a CANCEL verb has referred to it. On all other calls, the program is in the same state as when it last exited.
  10. If the called program has the INITIAL attribute, it is in its initial state every time it is called.
  11. Files contained in the called program are not open whenever the called program is in its initial state. Otherwise, the status and positioning of the contained files is the same as when the program last exited.
  12. If the ON EXCEPTION phrase is present and the called program cannot be initiated, statement-1 executes. If the called program cannot be initiated when there is no EXCEPTION phrase, a runtime error occurs and the program halts. A program cannot be initiated if program-name cannot be resolved using the rules described in Calling Subprograms.
  13. If the NOT ON EXCEPTION phrase is present and the called program is successfully initiated, statement-2 executes when the called program returns.
  14. The ON EXCEPTION and NOT ON EXCEPTION phrases execute in the original (parent) thread. The parent thread suspends long enough to determine whether or not the CALL will succeed. This allows it to determine whether to execute the EXCEPTION or NOT EXCEPTION case.
  15. A called program's file state and data items are distinct for each thread that exists at the time of the call (including the thread created by the CALL THREAD). Thus, if thread-1 calls program-a, and thread-2 calls program-a, there will be two copies of the data from program-a in memory, one set for each thread. Threads created in the called program, or any of its subprograms, share the called program's data and file state.
  16. The CALL PROGRAM verb is similar to the CHAIN verb. It causes the current run unit to terminate and initiates a new run unit. However, USING parameters are passed to data items specified in Linkage, just as they are for a standard CALL verb.

    Some (incorrect) usages of the CALL statement USING parameters from the Linkage section of the called program can result in so-called "intermediate" runtime errors that call installed error procedures. There currently are two such related errors: Use of a LINKAGE data item not passed by the caller, and Passed USING item smaller than corresponding LINKAGE item. A passed USING item that is larger than the corresponding Linkage item does not generate an error.

    Another runtime error can occur when the CALL statement attempts USING parameters of invalid structure or missing parameters. That kind of error is announced as Invalid or missing parameter, and it is also an "intermediate" type of runtime error that calls installed error procedures.

    See Appendix I. Library Routines for detailed discussion of the runtime error and exit procedures.

  17. When a CALL PROGRAM verb succeeds, all program switches are set to their off state. You can specify switches to be set on in the CALL PROGRAM statement. You accomplish this by specifying the switch names immediately after the program name in the statement. Each switch name must be alphabetic and must be preceded by a slash (/). For example, to turn on switches "A" and "B" you could use this statement:
    CALL PROGRAM "MYPROG/A/B" USING ...
  18. If the CALL PROGRAM verb cannot find the called program, and no EXCEPTION phrase has been specified, control passes to the next executable statement.
  19. The CALL PROGRAM verb accepts the presence of routines whose name begins with a "#" sign. When one of these routines is specified, the CALL PROGRAM statement is ignored. In ICOBOL, routines with these names are special-purpose system routines.
  20. If the RUN option is used, then program-name refers to the main program of another run unit. This run unit is initiated and continues until it executes a STOP RUN. At that point, control is returned to the next executable sentence in the calling program. Parameters are passed to the called run unit in the same manner as specified for the CHAIN statement.

    The called run unit is logically distinct from the calling run unit. It may call programs that are active in the calling unit without generating an error. External areas are associated with a logical run unit, so that a new run unit does not have access to external areas created by the calling run unit. Take care that file records locked by the calling run unit do not interfere with the called run unit, because there will be no opportunity for the caller to release its records while the called unit is active.

    type-ahead is retained both when the new run unit is called and upon return from it.

    The precise amount of memory required for the runtime varies by platform and is affected by configuration variables such as V_BUFFERS and by any products or C routines you have linked in. When the CALL RUN executes, the memory associated with the new run unit is allocated, and the old run unit (with its attendant memory) remains active. Memory allocated by the runtime for program code is freed automatically at the STOP RUN in the called program. Memory used for open windows and V_BUFFERS is not freed until the runtime exits. You should explicitly free any memory that you allocated with the M$ALLOC (Dynamic Memory Routine) otherwise this memory is not freed until the runtime exits.

  21. A special register named RETURN-CODE is automatically created by the compiler and is shared by all programs of a run unit. This special register is defined as:
    77  RETURN-CODE  SIGNED-LONG, EXTERNAL.

    If you call a C program via the direct interface, the return value of the C function is placed into this register. If you call the SYSTEM library routine, the status of the call is placed into this register. The verbs EXIT, STOP, and GOBACK can also place a value into the RETURN-CODE register. The compiler also creates an unsigned version of the return code called RETURN-UNSIGNED. It has the following implied definition:

    77  RETURN-UNSIGNED
        REDEFINES RETURN-CODE 
        UNSIGNED-LONG, EXTERNAL.
  22. RETURN-CODE (and RETURN-UNSIGNED) are unique to each COBOL thread. This insures one thread's return values do not overwrite those of another thread. The static return-code variable available to 'C' subroutines is copied into the appropriate COBOL special register when a called 'C' routine returns.
  23. If the RETURNING phrase is used, then the return value of the called program is moved to return-val. This is accomplished by the following rule:
    1. If return-val is a signed data item, then the value of RETURN-CODE is moved to return-val according to the rules of the MOVE statement.
    2. If return-val is unsigned, then RETURN-UNSIGNED is moved instead.
  24. You should avoid using RETURN-CODE or RETURN-UNSIGNED for return-val. This is pointless because, after assigning a value to return-val, the CALL statement restores the previous value of RETURN-CODE.
  25. On Windows systems, if you CALL a DLL, the runtime assumes that the DLL returns a long (at least 32 bits of data). This ensures that all of the data returned from the DLL is captured. However, in situations where the DLL returns less than 32 bits of data (such as a DLL that returns a short), some of the data might be random. To get the right size for the return value of DLLs, use the RETURNING phrase and set the receiving variable to the same size as the DLL's return value. The easiest way to do this is to declare the receiving variable to be the same type as the DLL's return type. For example, if the DLL MYDLL returns an int, you could do the following:
    77  RETURN-VAL       SIGNED-INT.
    CALL "MYDLL" RETURNING RETURN-VAL.
  26. After return-val is set, RETURN-CODE is set to the value it had immediately prior to the CALL statement. Thus the called program does not affect the value of RETURN-CODE in the calling program.
  27. If the CALL statement fails with an exception, then return-val is not updated.
  28. You may pass floating-point data to subroutines normally with the CALL verb. Note that you may not pass a floating-point item BY VALUE. This restriction exists for portability reasons (some machines pass floating-point using a convention different from that used for integer items). You should pass floating-point items BY REFERENCE. This will pass a pointer to the item, which the receiving routine can then retrieve by de-referencing the pointer.
  29. A program may directly or indirectly call itself. A CALL statement that calls the active program (itself) is a recursive call. For more information, see the RECURSION configuration variable. For information on sharing data in recursively called programs (such as in the HP COBOL environment), see the RECURSION_DATA_GLOBAL configuration variable.
  30. Errors that occur as a result of the CALL statement USING parameters from the Linkage section of the called program belong to an intermediate type of runtime errors that call installed error procedures. There are two such errors: Use of a LINKAGE data item not passed by the caller, and Passed USING item smaller than corresponding LINKAGE item.
Passing File Handles
  1. For compatibility with HP COBOL, a file handle is automatically passed BY VALUE unless it is immediately preceded by a BY REFERENCE or BY CONTENT specification. File handles passed to COBOL subroutines must be preceded with BY REFERENCE or BY CONTENT because COBOL routines cannot take BY VALUE parameters.
  2. If the called subroutine is a COBOL routine, the handle passed is PIC S9(4) COMP-5. You can override this with the compiler option --fileIdSize=# where # is either 2, 4, or 8 to specify the number of bytes you want in the passed integer.
  3. If the called subroutine is not COBOL, the handle is passed as a signed native integer using the host's default integer size.
  4. The file handle passed is the host file system's identifying value for the open file. For all current implementations, this is the value returned by the C open function. If the host file system does not have this information available, then -1 is used instead. This can happen if the host system is not a file (e.g. Acu4GL for Oracle) or the host system does not provide a way of obtaining the handle (e.g. C-ISAM interface). Files served by AcuServer® also use -1 because there is no useful way to use a remote process' open file handle.
  5. For Vision files in the multi-file format (Versions 4, 5, or 6), the handle used is the handle of the first data segment (this is the same file used when opening the file).
  6. It is best to avoid performing actual I/O on the file using this file handle because the COBOL file system will be unaware of any state changes to the file and may perform incorrectly. It is possible to corrupt data this way.