PL/I and C routines communicate by passing and returning data of equivalent data types. PL/I and non-PL/I routines should not communicate by using external static variables. Table 29 lists the scalar data types which are equivalent between PL/I and C.
| C Data Type | PL/I Data Type |
|---|---|
| signed char | FIXED BIN(7,0) |
| unsigned char | UNSIGNED FIXED BIN(8,0) or CHAR(1) |
| signed short | FIXED BIN(15,0) |
| unsigned short | UNSIGNED FIXED BIN(16,0) |
| signed (long) int | FIXED BIN(31,0) |
| unsigned (long) int | UNSIGNED FIXED BIN(31,0) |
| float | FLOAT BIN(21) FLOAT DEC(6) |
| double | FLOAT BIN(53) FLOAT DEC(16) |
| long double | FLOAT BIN(64) FLOAT DEC 18) |
| enum | ORDINAL |
| <non-function-type> * | POINTER or HANDLE |
| <function-type> * | ENTRY LIMITED |
As is illustrated in the last row of the table, a C function pointer is not equivalent to a PL/I entry variable unless the entry variable is LIMITED. Errors caused by this mistake are hard to detect.
Arrays of equivalent types are equivalent as long as they have the same number of dimensions and the same lower and upper bounds. In C, you cannot specify lower bounds, and the actual upper bound is one less than the number you specify. For example, consider this array declared in C:
short x [ 6 ];
In PL/I, the array would be declared as follows:
dcl x(0:5) fixed bin(15);
Structures and unions of equivalent types are also equivalent if their elements are mapped to the same offsets. The offsets are the same if there is no padding between elements. If the elements of a structure (or union) are all UNALIGNED, PL/I does not use padding. When some elements are ALIGNED, you can determine if there is any padding by examining the AGGREGATE listing. PL/I regards strings as scalars but C does not; therefore, none of the previous discussion applies to strings.
C bit fields have only nominal resemblance to PL/I bit strings.
C Structure
struct { unsigned byte1 :8;
unsigned byte2 :8;
unsigned byte3 :8;
unsigned byte4 :8;
} bytes;PL/I Structure
dcl
1 bytes,
2 byte1 bit(8),
2 byte2 bit(8),
2 byte3 bit(8),
2 byte4 bit(8);Other C compilers would map the original structure with the bytes reversed so that it would be equivalent to this PL/I structure.
PL/I Structure
dcl
1 bytes,
2 byte4 bit(8),
2 byte3 bit(8),
2 byte2 bit(8),
2 byte1 bit(8);Strictly speaking, C has no character strings, but only pointers to char. However, by common usage, a C string is a sequence of characters the last of which has the value '00'X. Thus, in the example below, address is a C 'string' that could hold up to 30 non-null characters.
char address [ 31 ];
The following PL/I declare most closely resembles the C 'string'.
dcl address char(30) varyingz;
In the declarations of C functions, strings are usually declared as char*. For example, the C library function strcspn could be declared as:
int strcspn( char * string1, char * string2 );
The PL/I declare for the same function would be:
dcl strcspn entry( char(*) varyingz,
char(*) varyingz )
returns( fixed bin(31) );
In the preceding examples, both the C and PL/I declarations are incomplete. Complete versions are given and explained later in this chapter.