IBM
Contents Index Previous Next



C Specific Package ctypes


IBM Rational offers a special package ctypes that contains data types and generators that match C. It is described in detail in The ADT Library. The ctypes package should be used in the following cases:

The tables below list the data types and generators in ctypes and their C counterparts.

SDL Sort Corresponding C Type
ShortInt

short int

LongInt

long int

UnsignedShortInt

unsigned short int

UnsignedInt

unsigned int

UnsignedLongInt

unsigned long int

Float

float

Charstar

char *

Voidstar

void *

Voidstarstar

void **

SDL Generator Corresponding C Declarator
Carray

C array, i.e. []

Ref

C pointer, i.e. *

The rest of this section explains how these data types and generators can be used in SDL.

Different Int Types and Float

ShortInt, LongInt, UnsignedShortInt, UnsignedInt, UnsignedLongInt are all defined as syntypes of Integer, so from an SDL point of view, these data types are really the same, and the normal Integer operators can be used on these types. The only difference is that the code that is generated for these types is different. Float is defined as a syntype of Real.

Charstar, Voidstar, Voidstarstar

Charstar represents character strings (i.e. char *) in C. Charstar is not the same as the SDL predefined type Charstring! Charstar is useful when accessing C functions and data types that use char *. In other cases it is better to use Charstring instead (see also Charstring). Conversion operators between Charstar and Charstring are available (see below).

Voidstar corresponds to void * in C. This type should only be used when accessing C functions that have void * parameters, or that return void * (in which case it is advised to "cast" the result directly to another type).

Voidstarstar corresponds to void ** in C. This type is used in combination with the Free procedure described in Using Pointers in SDL. In rare cases this type is also needed to access C functions.

The following conversion operators in ctypes are useful:

cstar2cstring : Charstar   -> CharString;
cstring2cstar : CharString -> Charstar;
cstar2vstar   : Charstar   -> Voidstar;
vstar2cstar   : Voidstar   -> Charstar;
cstar2vstarstar : Charstar -> Voidstarstar;

These operators have the following behavior:

The Carray Generator

The generator Carray in package ctypes is useful to define arrays that have the same properties as C arrays. Carray takes two generator parameters; an integer value and a component sort.

Example 33 : Carray instantiation

newtype IntArr Carray(10, Integer)
endnewtype;

The defined type IntArr is an array of 10 integers with indices 0 to 9, corresponding to the C type

typedef int IntArr[10]; 

Two operators are available on instantiations of Carray; modify! to change one element of the array, and extract! to get the value of one element in the array. These operators are used in the same way as in normal SDL arrays, see Array. There is no (. ... .) notation provided for denoting values of whole CArrays.

    modify!  : Carray, Integer, Itemsort -> Carray;
    extract! : Carray, Integer          -> Itemsort;

Example 34 : Use of Carray in SDL

DCL v IntArr, i Integer;

TASK v(0) := 3; /* modifies one element */
TASK i := v(9); /* extracts one element */

If a C array is used as parameter of an operator, it will be passed by address, just as in C. This makes it possible to write operators that change the contents of the actual parameters. In standard SDL this would not be possible.

The Ref Generator

The generator Ref in package ctypes is used to define pointer types. The following example illustrates how to use this generator.

Example 35 : Defining a pointer type

newtype ptr Ref(Integer)
endnewtype;

The sort ptr is a pointer to Integer.

Standard SDL has no pointer types. Pointers have properties that cannot be defined in normal SDL. Therefore they should be used very carefully. Before explaining how to use the Ref generator, it is worthwhile to list some of the dangers of using pointers in SDL.

Pointers Will Lead to Data Inconsistency

If more than one process can read/write to the same memory location by means of pointers, data inconsistency can and will occur! Some examples:

Even though tools such as the SDL Simulator and SDL Explorer will be able to detect a number of errors regarding pointers, there are situations that cannot be detected with these tools! This is because the Explorer and Simulator assume a scheduling atomicity of at best one SDL symbol at a time. This may not hold in target operating systems where one process can be interrupted at any time (pre-emptive scheduling). If pointers are used, data is totally unprotected, and data inconsistency may occur, even though the Explorer did not discover any problems! All these problems can be avoided by using SDL constructs for accessing data, like remote procedures and signal exchange.

Caution!

For the above stated reasons, NEVER PASS POINTERS TO ANOTHER PROCESS! Not in an output, not in a remote procedure call, not in a create, and not by exported/revealed variables!

And if you do not obey this rule anyway: after passing a pointer, release immediately the "old" pointer to prevent having several pointers to the same data area. For example (for some pointer p):

OUTPUT Sig(p) TO ...;
TASK p := Null;

Pointers Are Unpredictable

If you have an SDL system that always works except during demonstrations, then you have used pointers! Bugs with pointers may be very hard to discover, as a system may (accidentally) behave correctly for a long time, but then suddenly strange things may happen. Finding such bugs may take very long time; in rare cases you might not find them at all!

Caution!

BUGS CAUSED BY POINTERS MAY BE HARD TO FIND!

Pointers Do Not Work in Real Distributed Systems

If an SDL system is "really" distributed, i.e. where processes have their own memory space, it makes no sense to send a pointer to another process, as the receiving process will not be able to do anything with it. Therefore, by communicating pointers to other processes, limitations are posed on the architecture of the target implementation.

Pointers Are Not Portable

The Ref generator and its operators are completely IBM Rational-specific. It is highly unlikely that SDL systems using pointers will run on other SDL tools.

Using Pointers in SDL

If you still want to use pointers in SDL after all these warnings, this section explains how to do this. A pointer type created by the Ref generator always has a literal value Null (corresponds to NULL in C), which is also the default value. The literal Alloc is used for the dynamic creation of new memory. Examples are given later.

Note:

It is up to the user to keep track of all dynamically allocated data areas and to free them when they are no longer needed.

The following operators are available for Ref types:

"*>"  : Ref, Itemsort -> Ref;
"*>"  : Ref -> Itemsort;
"&"   : Itemsort -> Ref;
make! : Itemsort -> Ref;
free  : in/out Ref;
"+"   : Ref, Integer -> Ref;  
"-"   : Ref, Integer -> Ref;
vstar2ref : Voidstar -> Ref;
ref2vstar : Ref -> Voidstar;
ref2vstarstar : Ref -> Voidstarstar;  

Furthermore, the following procedure is defined:

procedure Free; fpar p Voidstarstar; external;

These operators can be used in the following way:

Example 36 : Use of the Ref operators

NEWTYPE ptr Ref(Integer)
ENDNEWTYPE;

DCL p ptr, 
    i, j Integer;

TASK p := alloc; /* creates dynamically a new      
                    integer; p points at it */
/* here it should be checked that p != Null */
TASK p*> := 10;  /* changes contents of p */
CALL free(p);  /* releases the integer */
TASK p := (. 10 .); /* allocate and set to 10 */
CALL free(p);  /* releases the integer again */
TASK p := &i;  /* p now points to i */
TASK p*> := 5; /* changes contents of p, i.e. also
                  i is changed! */
TASK j := p*>; /* gets contents of p (=5) */

Using Linked Structures with Pointers

Pointers are useful when defining linked structures like lists or trees. In this section we give an example of a linked list containing integer values. Figure 43 shows an SDL fragment with data type definitions for a linked list, and part of a transition that actually builds a linked list. A list is represented by a pointer to an Item. Every Item contains a pointer next to the next item in the list. In the last item of the list, next = Null.

Figure 43 : Building a linked list

Figure 44 shows an SDL fragment where the sum of all elements in a list is computed. Note that this computation would never stop if there would be an element that points back in the list, just to illustrate how easy it is to make errors with pointers.

Figure 44 : Going through the list


http://www.ibm.com/rational
Contents Index Previous Next