About implementing operations in C

Because the C language does not directly support the concept of object operations, there are two issues that must be addressed when generating C code from object models:

Associating an operation with an object

Because each operation associated with an object is implemented as a global function in C, it must be provided with a context in the form of a pointer to the object on which it operates. In C++, this context is provided in the form of an implied this pointer as the first argument. In C, however, the this pointer is not available. Therefore, in IBM® Rational® Rhapsody® in C, the first argument to operations is generally a pointer to the object associated with the operation. This context pointer is conventionally called me. For example:

/*## operation close() */
void Valve_close(Valve* const me);

Because there is only one instance of a singleton object, the context pointer is not needed for singleton operations. See Singleton objects for more information.

You can change the name generated for the first argument using the C_CG::Operation::Me and C_CG::Operation::MeDeclType properties. The Me property specifies the string used for the first argument (for example, "me"). The MeDeclType property specifies the full type declaration for the first argument. Its default value is as follows:

$objectName* const

The objectName variable is replaced with the name of the object type. Adding a :i switch to the objectName variable truncates the name to leave only the uppercase letters. For example, using $objectName:i for an object named HomeHeatingSystem results in the name HHS.

Rational Rhapsody automatically inserts the me argument into code generated for operations, but it is important for you to remember to provide it when calling an operation of an object.

Naming of operations

Because C has a flat namespace for functions, Rational Rhapsody uses a naming convention to resolve namespace contentions. The convention used is to prefix each (public) operation with the name of the object on which it operates. (See Visibility of operations for information about different naming conventions for private operations.)

For example, the Valve object has two public operations: open() and close(). These operations are implemented as follows:

void Valve_open(struct Valve_t * const me);
void Valve_close(struct Valve_t * const me);

Feedback