Programming in C

Top  Previous  Next

XCICS supports C programs that have been compiled using:

Vendor specific ANSI/C Compiler (UNIX)
GNU GCC (UNIX & Linux)
Microsoft Visual Studio (Windows)

All the EXEC CICS commands available in COBOL and PL/I applications are also supported in C applications, with the exception of those commands related to nonstructured exception handling.

Also note the following programming considerations:

Exception handling

Nonstructured exception handling

The EXEC CICS commands related to nonstructured exception handling:

HANDLE ABEND LABEL(label)
HANDLE AID
HANDLE CONDITION
IGNORE CONDITION
PUSH HANDLE
POP HANDLE

are not supported in C applications. Use of these commands is diagnosed by the translator.

Condition handling

In a C application, every EXEC CICS command is treated as if it had the NOHANDLE or RESP option specified. This means that the set of "system action" transaction abends that result from a condition occurring but not being handled, is not possible in a C or C++ application. Control always flows to the next instruction, and it is up to the application to test for a normal response.

ABEND handling

HANDLE ABEND PROGRAM commands are allowed, but you cannot use PUSH HANDLE or POP HANDLE.

COMMAREA

The address of the communication area is passed as an argument to a C main function. Of course, C functions can still use ADDRESS COMMAREA to obtain the address of the communications area.

EIB

The address of the EIB is passed as an argument to a C main function. Of course, C functions can still use ADDRESS EIB to obtain the address of the EIB.

OVERFLOW conditions

If you want any OVERFLOW condition to be indicated in the RESP field on return from a SEND MAP command with the ACCUM option, you should specify the NOFLUSH option.

Return value

If you terminate a C program with an exit() function or the return statement, instead of a CICS RETURN command, the value passed through the exit() function is saved in the EIBRESP2 field of the EIB on return from the program.

Data declarations

The following data declarations are provided by CICS for C:

Execution interface block definitions (EIB)
BMS screen attributes definitions: C versions of the DFHBMSCA, DFHMSRCA, and DFHAID files are supplied by CICS, and may be included by the application programmer when using BMS.

The EIB declarations are enclosed in #ifndef and #endif lines, and are included in all translated files.

Restrictions

The following lists describe some of the restrictions that exist with C programs XCICS:

C and C++ languages do not support packed decimal data. The application has access to packed decimal data using the character string data type. No C or C++ standard library functions are available to perform arithmetic on this data, but you may write your own.
You can easily use HOURS, MINUTES, and SECONDS options. You may define expiration times using TIME or INTERVAL options if you provide functions to handle them in your application.
You can enter all CICS keywords in mixed case.
If you do not specify the LENGTH option on commands that support LENGTH (for example, READ, READNEXT, READPREV, and WRITE commands), the translator does not supply a default value. In effect, NOLENGTH is implicit for C programs.
The string handling functions in the C standard library use a null character as an end-of-string marker. Because XCICS does not recognize a null as an end-of-string marker, you must take care when using C or C++ functions, for example strcmp, to operate on XCICS data areas.
Two arguments, argc and argv, are normally passed to a C or C++ main function. argc denotes how many variables have been passed; argv is aarray of zero-terminated variable strings. In XCICS, the value of argc is 4 and the argv array contains:
oargv[0] contains the address of a zero-terminated string containing a copy of EIBTRNID
oargv[1] contains the address of the EIB block
oargv[2] contains the address of the COMMAREA if any or NULL
oargv[3] contains the EIBCALEN
oargv[4] contains NULL
Where CICS expects a fixed-length character string such as a program name, map name, or queue name, you must pad the literal with blanks up to the required length if it is shorter than expected.
BMS maps structure must be packed, that means aligned to 1 byte boundary. The xbms2mod utility automatically produces OS dependant packed C structs.

Passing arguments in C or C++

Arguments in C language are copied to the program stack at run time, where they are read by the function. These arguments can either be values in their own right, or they can be pointers to areas of memory that contain the data being passed. Passing a pointer is also known as passing a value by reference.

Other languages, such as COBOL and PL/I, usually pass their arguments by reference, which means that the compiler passes a list of addresses pointing to the arguments to be passed. This is the call interface supported by CICS. To pass an argument by reference, you prefix the variable name with &, unless it is already a pointer, as in the case when an array is being passed.

As part of the build process, the compiler may convert arguments from one data type to another. For example, an argument of type char may be converted to type short or type long.

When you send values from a C  program to XCICS, the translator takes the necessary action to generate code that results in an argument list of the correct format being passed to XCICS. The translator does not always have enough information to enable it to do this, but in general, if the argument is a single-character or halfword variable, the translator makes a precall assignment to a variable of the correct data type and passes the address of this temporary variable in the call.

When you receive data from XCICS, the translator prefixes the receiving variable name with &, which causes the C compiler to pass it values by reference rather than by value (with the exception of a character string name, which is left unchanged). Without the addition of &, the compiler would copy the receiving variable and then pass the address of the copy to CICS. Any promotion occurring during this copying could result in data returned by CICS being lost.

This table shows the rules that apply when passing values as arguments in EXEC CICS commands:

Data Type

Usage

Argument

Character literal  

Data value (sender)

The user must specify the character literal directly. The translator takes care of any required indirection.

Character variable (char)

Data-area (receiver)

The user must specify a pointer  to the variable, possibly by prefixing the variable name with &.                               

Character variable (char)

Data value (sender)

The user must specify the character variable directly. The translator takes care of any required indirection.

Character string literal

Name (sender)

The user can either code the string directly as a literal string or use a pointer which points to the first character of the string.                      

Character string variable

Data-area (receiver)

Name (render)

Whether receiving or sending, the argument should be the name of the character array containing the string--the address of the first element of the array.      

Integer variable (short, long, or int)  

Data-area (receiver)

The user must specify a pointer to the variable, possibly by prefixing the variable name with &.

Integer variable (short, long, or int)  

Data value (sender)

The user must specify the name of the variable. The translator looks after any indirection that is required.

Integer constant (short, long, or int)  

Data value (sender)

The user must specify the name of  the variable. The translator looks after any indirection that is required.

Structure or union

Data-area (sender)

Data-area (receiver)

The user must code the address of the start of the structure or union, possibly by prefixing its name with &.

Array (of anything)

Data-area (sender)

Data-area (receiver)

The translator does nothing. You must code the address of the first member of the array. This is normally done simply by coding the name of the array, which the compiler interprets as the address of the first member.

Pointer (to anything)

Data-area (sender)

Ptr-ref (receiver)

Whether receiving or sending, the argument should be the name of the variable that denotes the address of interest. The translator takes care of the extra level of indirection that is necessary to allow CICS to update the pointer.              

Note:  Receiver is where data is being received from CICS; Sender is where data is being passed to CICS.                            

Accessing the EIB

The address of the exec interface block (EIB) is passed as an argument to a C main function. C and C++ functions can use the ADDRESS EIB command too, to obtain the address of the EIB.

Addressability is achieved by using the command:

EXEC CICS ADDRESS EIB(dfheiptr);

Within a C application program, fields in the EIB are referred to in lower case and fully qualified as, for example, "dfheiptr->eibtrnid".

The following mapping of data types is used:

Halfword binary integers are defined as "short int"
Fullword binary integers are defined as "long int"
Single-character fields are defined as "unsigned char"
Character strings are defined as "unsigned char" arrays

Compiler considerations

On some C compilers (i.e. IBM C for AIX 5.0),  the 1 byte structure alignment, is not correctly handle. This causes errors when accessing BMS maps structures.

The GNU GCC compiler (3.x or higher) actually works correctly on all the platforms where XFRAME is available, therefore it is the suggestes compiler for C language XCICS application development.