14.2. Built-in C classes

The following C types are built into the extended library:
Sather Class          ANSI C type
C_CHAR                char
C_CHAR_PTR            char *
C_UNSIGNED_CHAR       unsigned char
C_UNSIGNED_CHAR_PTR   unsigned char *
C_SIGNED_CHAR         signed char
C_SIGNED_CHAR_PTR     signed char *
C_SHORT               short
C_SHORT_PTR           short *
C_INT                 int
C_INT_PTR             int *
C_LONG                long
C_LONG_PTR            long *
C_UNSIGNED_SHORT      unsigned short
C_UNSIGNED_SHORT_PTR  unsigned short *
C_UNSIGNED_INT        unsigned int
C_UNSIGNED_INT_PTR    unsigned int *
C_UNSIGNED_LONG       signed long
C_UNSIGNED_LONG_PTR   unsigned long *
C_FLOAT               float
C_FLOAT_PTR           float *
C_DOUBLE              double
C_DOUBLE_PTR          double *
C_LONG_DOUBLE         long double
C_LONG_DOUBLE_PTR     long double *
C_PTR                 void *
C_PTRDIFF_T           ptrdiff_t
C_SIZE_T              size_t

Variable of the built-in types are binary compatible with the corresponding C types. These classes define appropriate creation routines which may be used for convenient casting between Sather and C types. Also, many basic operations on the built-in C types are provided by the library. For example, it is not necessary to call external C code to add two C_INT variables. All operations on built-in C types defined by the library have the ANSI C semantics. Syntactic sugar for the built-in C types is defined exactly as for "regular" Sather classes.
-- "basic" operations may be done in Sather
a:C_LONG := #(10);
b:C_LONG := #(5);
c::= a + b;
#OUT + c.str + " should be 15\n";

'AREF{T}' defines a routine 'array_ptr:C_PTR' which may be used to obtain a pointer to the first item in the array portion of Sather objects. The external routine may modify the contents of this array portion, but must not store the pointer; there is no guarantee that the pointer will remain valid after the external routine returns. This restriction ensures that the Sather type system and garbage collector will not be corrupted by external code while not sacrificing efficiency for the most important cases.

The following example shows how a Sather array could be passed to external C functions:
/* ANSI C prototypes for functions called from Sather */
void clear(void* p, int size);
void better_clear(int *, int size);

external C class PROCESS_ARRAYS is
   -- routines implemented externally in C that zero
   -- all elements in an integer array of a specified size
   clear(p:C_PTR, size:C_INT);
   better_clear(p:C_INT_PTR, size:C_INT);

-- This code demonstrates how to call external C routines
a:ARRAY{INT} := #(10);
-- this call just passes an array portion and avoids typecheking
-- This is not recommended ("a" could be of type ARRAY{CHAR} and the
-- call would still compile resulting in a runtime error)
PROCESS_ARRAYS::clear(a.arr_ptr, #(a.size);

-- this is a better sequence achieving the same result
-- if "a" is not an array of integers, an error is reported
PROCESS_ARRAYS::better_clear(#C_INT_PTR(a), #(a.size));

The second call is type-safe. It exploits the constructor for C_INT_PTR that allows creation from ARRAY{INT}.