In addition to the above basic types, IDL also supports three constructed types: struct, union, and enum. The structure and enumeration types are specified in IDL the same as they are in C and C++ [Kernighan-Ritchie references: struct, p. 128; union, p. 147; enum, p. 39], with the following restrictions:
Unlike C/C++, recursive type specifications are allowed only through the use of the sequence template type (see below).
Unlike C/C++, structures, discriminated unions, and enumerations in IDL must be tagged. For example, "struct { int a; ... }" is an invalid type specification. The tag introduces a new type name.
In IDL, constructed type definitions need not be part of a typedef statement; furthermore, if they are part of a typedef statement, the tag of the struct must differ from the type name being defined by the typedef. For example, the following are valid IDL struct and enum definitions:
struct myStruct { long x; double y; }; /* defines type name myStruct*/ enum colors { red, white, blue }; /* defines type name colors */
By contrast, the following definitions are not valid:
typedef struct myStruct { /* NOT VALID */ long x; double y; } myStruct; /* myStruct has been redefined */ typedef enum colors { red, white, blue } colors; /* NOT VALID */
The valid IDL struct and enum definitions shown above are translated by the SOM Compiler into the following definitions in the C and C++ bindings, assuming they were declared within the scope of interface "Hello":
typedef struct Hello_myStruct { /* C/C++ bindings for IDL struct */ long x; double y; } Hello_myStruct; typedef unsigned long Hello_colors; /* C/C++ bindings for IDL enum */ #define Hello_red 1UL #define Hello_white 2UL #define Hello_blue 3UL
When an enumeration is defined within an interface statement for a class, then within C/C++ programs, the enumeration names must be referenced by prefixing the class name. For example, if the colors enum, above, were defined within the interface statement for class Hello, then the enumeration names would be referenced as Hello_red, Hello_white, and Hello_blue. Notice the first identifier in an enumeration is assigned the value 1.
All types and constants generated by the SOM Compiler are fully qualified. That is, prepended to them is the fully qualified name of the interface or module in which they appear. For example, consider the following fragment of IDL:
module M { typedef long long_t; module N { typedef long long_t; interface I { typedef long long_t; }; }; };
That specification would generate the following three types:
typedef long M_long_t; typedef long M_N_long_t; typedef long M_N_I_long_t;
For programmer convenience, the SOM Compiler also generates shorter bindings, without the interface qualification. Consider the next IDL fragment:
module M { typedef long long_t; module N { typedef short short_t; interface I { typedef char char_t; }; }; };
In the C/C++ bindings of the preceding fragment, you can refer to "M_long_t" as "long_t", to "M_N_short_t" as "short_t", and to "M_N_I_char_t" as "char_t".
However, these shorter forms are available only when their interpretation is not ambiguous. Thus, in the first example the shorthand for "M_N_I_long_t" would not be allowed, since it clashes with "M_long_t" and "M_N_long_t". If these shorter forms are not required, they can be ignored by setting #define SOM_DONT_USE_SHORT_NAMES before including the public header files, or by using the SOM Compiler option -mnouseshort so that they are not generated in the header files.
In the SOM documentation and samples, both long and short forms are illustrated, for both type names and method calls. It is the responsibility of each user to adopt a style according to personal preference. It should be noted, however, that CORBA specifies that only the long forms must be present.