Embedded C declarations

The declarations described in this section are supported by the embedded C compiler for modifying your C data and functions. These declarations allow you to specify a compilation model, : code and data segments, structure packing and naming conventions. These declarations must be placed at the beginning of your Prolog file before Prolog code or C code and data declarations. The following sections describe each of the compiler directives.

C code and data declarations

The embedded C compiler supports virtually all ANSI standard C declarations and preprocessor directives and can be used in any compiled Prolog module. A file may contain code and data declarations placed within :- c and :- prolog specifiers. The format for a file containing C declarations is displayed below.

Prolog declarations :- c. C code and data declarations :- prolog. Prolog code

The following is a brief listing of the C data types, declarations, and preprocessor directives supported by the embedded C compiler. Due to the complexity of the various declaration and directive formats, a description of the formats is reserved for C reference manuals. Thus, you should refer to a C reference manual for format specifications and any other detailed information.

Note: all C declarations must end with a semicolon (;).

C numeric type declarations

The following table lists the C simple numeric data types supported by Arity/Prolog32, as well as the storage and range of values associated with each.

TypeStorageRange of values
char1 byte-128 to 127
int2 bytes-32,768 to 32,767
short2 bytes-32,768 to 32,767
long4 bytes-2,147,483,648 to 2,147,483,648
unsigned char1 byte0 to 256
unsigned2 bytes0 to 65,535
unsigned short2 bytes0 to 65,535
unsigned long4 bytes0 to 4,294,967,295
float4 bytes3.4E-38 to 3.4E+38
double8 bytes1.7E-308 to 1.7E+308

A simple numeric declaration specifies the variable's name and type. You can declare more than one variable in a single type declaration. For example, the following declares the variables x and y as longs and the variable total as a double:

long x,y; double total;

Note: the long double data type is not supported by Arity/Prolog32.

Enumeration declarations

An enumeration declaration is used to declare an enumeration variable. For example:

enum month {january, february, march, april, may, june} halfyear;

This enumeration declaration has the name month. The variable halfyear is an enumeration variable.

Struct declarations

A struct declaration is used to declare structure variables. For example:

struct student { char name[20]; int id, level; float pntavg; } record;

The structure variable record is assigned the structure definition student. The student structure consists of a character array, two integers, and a floating-point number.

Union declarations

A union declaration is used to declare a union variable and the members of the union. For example:

union sign { int sint; unsigned usint; } number;

This union declaration declares the union variable number which has the members sint (a signed integer) and usint (an unsigned integer). The union is named sign.

Array declarations

An array can have a single dimension, or multiple dimensions. An array declaration defines the name of the array and the type of the elements of the array. For example, the following define a single dimension array consisting of 15 elements of type double and a three dimensional array of integers named score:

double results[15];i nt score[3][20][30];

Arrays are allocated in "row-major" order. For example, the array int foo[3][2] is allocated as:

foo[0][0] foo[0][1] foo[1][0] foo[1][1] foo[2][0] foo[2][1]

Pointer declarations

A pointer declaration is used to declare a pointer variable and indicate the object to which it points. An asterisk (*) is used to represent a pointer. A pointer declaration always includes a type declaration indicating the type of the object to which the pointer points. For example, the following define pointers to two longs and a character array:

long *lp1, *lp2; char *months[9];

Function declarations

A function declaration declares the name and return type of a function and may specify the types, parameter names and number of arguments to the function. For example, the following defines a function named op1 which takes two arguments of type long and returns a character:

char op1(long,long);

If you are declaring a function which takes no arguments, use void as the argument specification. The following function takes no arguments and returns an integer:

int status(void);

If you are defining a function which does not return a value, use void as the return type specifier. The following function takes a character array and pointer to a long as arguments. There is no return value for the function.

void id(char [], long *);

Complex declarations

A complex declaration can combine any of the previously described declarations, with the following exceptions:

  • An array cannot have functions as its elements.
  • A function cannot return an array or a function.

For example, the following defines a variable var which is a 5x5 array of pointers to pointers to unions with two members:

union sign { int a; unsigned b; } **var[5][5];

Storage classes

Arity/Prolog32 supports two storage class specifiers: extern and static. The use of storage class specifiers when declaring C variables applies as follows:

static

Variables which are explicitly declared as static are defined only for the module in which they appear.

extern

The extern declaration is used to declare a variable which is used in the current module but defined in a different module. Variables declared as extern cannot be initialized.

no specifier (global or common)

If no storage class specifier is used when declaring a variable, then the variable is considered global if it is initialized, otherwise it is common. A global variable can be accessed by other modules with an extrn specifier, a common variable must be common in each module. Static and global variables may be initialized.

Typedef declaration The typedef declaration can be used to provide a synonym for a declared type. This synonym can be used in any other type declarations. For example, the following declares the synonym pint for the data type of a pointer to an integer: typedef *int pint;

Note: If you wish to use complex types in Prolog predicates, you will need to have a typedef for the type.

Preprocessor directives

The following preprocessor directives are supported by the embedded C compiler:

#define #elif #else #endif #if #ifdef #ifndef #include #undef

Items not supported

The following items are not supported by the embedded C compiler:

  • The huge data type modifier.
  • The volatile data type.
  • The const data type.
  • The auto storage class.
  • The register storage class.
  • The #line preprocessor directive.
  • Bitfields.
  • The #define preprocessor definitions are only valid within the :-c. and :-prolog specifiers.
  • Initializers for arrays and strings.

Only C variables may be defined in embedded C. C functions may be declared, but Arity/Prolog32 does not compile C functions.