Interface Definition Language (v42)
Interface Definition Language (v42)
Version 4.2
LICENSES
The companies listed above have granted to the Object Management Group, Inc. (OMG) a nonexclusive, royalty-free, paid up,
worldwide license to copy and distribute this document and to modify this document and distribute copies of the modified
version. Each of the copyright holders listed above has agreed that no person shall be deemed to have infringed the copyright
in the included material of any such copyright holder by reason of having used the specification set forth herein or having
conformed any computer software to the specification.
Subject to all of the terms and conditions below, the owners of the copyright in this specification hereby grant you a fully-paid
up, non-exclusive, nontransferable, perpetual, worldwide license (without the right to sublicense), to use this specification to
create and distribute software and special purpose specifications that are based upon this specification, and to use, copy, and
distribute this specification as provided under the Copyright Act; provided that: (1) both the copyright notice identified above
and this permission notice appear on any copies of this specification; (2) the use of the specifications is for informational
purposes and will not be copied or posted on any network computer or broadcast in any media and will not be otherwise resold
or transferred for commercial purposes; and (3) no modifications are made to this specification. This limited permission
automatically terminates without notice if you breach any of these terms or conditions. Upon termination, you will destroy
immediately any copies of the specifications in your possession or control.
PATENTS
The attention of adopters is directed to the possibility that compliance with or adoption of OMG specifications may require use
of an invention covered by patent rights. OMG shall not be responsible for identifying patents for which a license may be
required by any OMG specification, or for conducting legal inquiries into the legal validity or scope of those patents that are
brought to its attention. OMG specifications are prospective and advisory only. Prospective users are responsible for
protecting themselves against liability for infringement of patents.
DISCLAIMER OF WARRANTY
WHILE THIS PUBLICATION IS BELIEVED TO BE ACCURATE, IT IS PROVIDED "AS IS" AND MAY CONTAIN
ERRORS OR MISPRINTS. THE OBJECT MANAGEMENT GROUP AND THE COMPANIES LISTED ABOVE MAKE
NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THIS PUBLICATION, INCLUDING
BUT NOT LIMITED TO ANY WARRANTY OF TITLE OR OWNERSHIP, IMPLIED WARRANTY OF
MERCHANTABILITY OR WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE. IN NO EVENT
SHALL THE OBJECT MANAGEMENT GROUP OR ANY OF THE COMPANIES LISTED ABOVE BE LIABLE FOR
ERRORS CONTAINED HEREIN OR FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL,
RELIANCE OR COVER DAMAGES, INCLUDING LOSS OF PROFITS, REVENUE, DATA OR USE, INCURRED BY
ANY USER OR ANY THIRD PARTY IN CONNECTION WITH THE FURNISHING, PERFORMANCE, OR USE OF
THIS MATERIAL, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
The entire risk as to the quality and performance of software developed using this specification is borne by you. This
disclaimer of warranty constitutes an essential part of the license granted to you to use this specification.
TRADEMARKS
CORBA , CORBA logos , FIBO , Financial Industry Business Ontology®, FINANCIAL INSTRUMENT GLOBAL
® ® ®
IDENTIFIER®, IIOP®, IMM®, Model Driven Architecture®, MDA®, Object Management Group®, OMG®, OMG Logo®,
SoaML®, SOAML®, SysML®, UAF®, Unified Modeling Language®, UML®, UML Cube Logo®, VSIPL®, and XMI® are
registered trademarks of the Object Management Group, Inc.
For a complete list of trademarks, see: http://www.omg.org/legal/tm_list.htm. All other products or company names mentioned
are used for identification purposes only, and may be trademarks of their respective owners.
COMPLIANCE
The copyright holders listed above acknowledge that the Object Management Group (acting itself or through its designees) is
and shall at all times be the sole entity that may authorize developers, suppliers and sellers of computer software to use
certification marks, trademarks or other special designations to indicate compliance with these materials.
Software developed under the terms of this license may claim compliance or conformance with this specification if and only if
the software compliance is of a nature fully matching the applicable compliance points as stated in the specification. Software
developed only partially matching the applicable compliance points may claim only that the software was based on this
specification, but may not claim compliance or conformance with this specification. In the event that testing suites are
implemented or approved by Object Management Group, Inc., software developed using this specification may claim
compliance or conformance with the specification only if the software satisfactorily completes the testing suites.
All OMG specifications are subject to continuous review and improvement. As part of this process we encourage readers to
report any ambiguities, inconsistencies, or inaccuracies they may find by completing the Issue Reporting Form listed on the
main web page http://www.omg.org, under Documents, Report a Bug/Issue (http://issues.omg.org/issues/create-new-issue).
Table of Contents
Interface Definition Language™ ............................................... i
Table of Contents ..................................................................... i
Tables .................................................................................... iii
Figures ................................................................................... iv
1 Scope ................................................................................. 1
2 Conformance Criteria ......................................................... 3
3 Normative References ........................................................ 5
4 Terms and Definitions......................................................... 7
5 Symbols .............................................................................. 9
6 Additional Information ....................................................... 11
6.1 Acknowledgments .................................................................................. 11
6.2 Specification History............................................................................... 11
7 IDL Syntax and Semantics ............................................... 13
7.1 Overview ................................................................................................ 13
7.2 Lexical Conventions ............................................................................... 14
7.2.1 Tokens ....................................................................................................17
7.2.2 Comments ..............................................................................................17
7.2.3 Identifiers ................................................................................................18
7.2.4 Keywords ................................................................................................19
7.2.5 Other Characters Recognized by IDL .....................................................20
7.2.6 Literals ....................................................................................................20
7.3 Preprocessing ........................................................................................ 23
7.4 IDL Grammar ......................................................................................... 24
7.4.1 Building Block Core Data Types .............................................................24
7.4.2 Building Block Any ..................................................................................43
7.4.3 Building Block Interfaces – Basic ...........................................................45
7.4.4 Building Block Interfaces – Full ..............................................................52
7.4.5 Building Block Value Types ....................................................................54
7.4.6 Building Block CORBA-Specific – Interfaces ..........................................58
7.4.7 Building Block CORBA-Specific – Value Types .....................................64
7.4.8 Building Block Components – Basic .......................................................70
7.4.9 Building Block Components – Homes ....................................................74
7.4.10 Building Block CCM-Specific ..................................................................77
7.4.11 Building Block Components – Ports and Connectors .............................83
7.4.12 Building Block Template Modules ..........................................................86
IDL, v4.2 i
7.4.13 Building Block Extended Data-Types .....................................................90
7.4.14 Building Block Anonymous Types ..........................................................96
7.4.15 Building Block Annotations .....................................................................97
7.4.16 Relationships between the Building Blocks ..........................................102
7.5 Names and Scoping ............................................................................. 102
7.5.1 Qualified Names ...................................................................................102
7.5.2 Scoping Rules and Name Resolution ...................................................104
7.5.3 Special Scoping Rules for Type Names ...............................................106
9 Profiles............................................................................ 119
9.1 Overview .............................................................................................. 119
9.2 CORBA and CCM Profiles ................................................................... 119
9.2.1 Plain CORBA Profile.............................................................................119
9.2.2 Minimum CORBA Profile ......................................................................119
9.2.3 CCM Profile ..........................................................................................120
9.2.4 CCM with Generic Interaction Support Profile ......................................120
9.3 DDS Profiles......................................................................................... 121
9.3.1 Plain DDS Profile ..................................................................................121
9.3.2 Extensible DDS Profile .........................................................................121
9.3.3 RPC over DDS Profile ..........................................................................121
ii IDL, v4.2
Tables
Table 7-1: IDL EBNF .......................................................................................................... 14
Table 7-2: Characters ........................................................................................................... 14
Table 7-3: Decimal digits .................................................................................................... 15
Table 7-4: Graphic characters ............................................................................................. 16
Table 7-5: Formatting characters ......................................................................................... 17
Table 7-6: All IDL keywords .............................................................................................. 19
Table 7-7: Punctuation ........................................................................................................ 20
Table 7-8: Tokens ................................................................................................................ 20
Table 7-9: Escape sequences................................................................................................ 21
Table 7-10: List of pre-existing non-terminals in IDL rules ................................................ 24
Table 7-11: Operations on fixed-point decimal constants ................................................... 31
Table 7-12: 2's complement numbers .................................................................................. 31
Table 7-13: Integer types ..................................................................................................... 34
Table 7-14: Keywords specific to Building Block Core Data Types .................................. 43
Table 7-15: Keywords specific to Building Block Any ....................................................... 44
Table 7-16: Keywords specific to Building Block Interfaces – Basic ................................. 51
Table 7-17: Keywords specific to Building Block Value Types ......................................... 57
Table 7-18: Keywords specific to Building Block CORBA-Specific – Interfaces.............. 64
Table 7-19: Possible inheritance relationships between value types and interfaces ............ 68
Table 7-20: Keywords specific to Building Block CORBA-Specific – Value Types ......... 69
Table 7-21: Keywords specific to Building Block Components – Basic ............................ 73
Table 7-22: Keywords specific to Building Block Components – Homes .......................... 76
Table 7-23: Keywords specific to Building Block CCM-Specific ...................................... 82
Table 7-24: Keywords specific to Building Block Components – Ports and Connectors ... 86
Table 7-25: Keywords specific to Building Block Template Modules ............................... 89
Table 7-26: Ranges for all Integer types .............................................................................. 95
Table 7-27: Keywords specific to Building Block Extended Data-Types ........................... 96
Table 7-28: Keywords specific to Building Block Annotations ........................................ 100
iv IDL, v4.2
Preface
About the Object Management Group
OMG
Founded in 1989, the Object Management Group, Inc. (OMG) is an open membership, not-for-profit computer industry
standards consortium that produces and maintains computer industry specifications for interoperable, portable and reusable
enterprise applications in distributed, heterogeneous environments. Membership includes Information Technology vendors,
end users, government agencies and academia.
OMG member companies write, adopt, and maintain its specifications following a mature, open process. OMG's specifications
implement the Model Driven Architecture® (MDA®), maximizing ROI through a full-lifecycle approach to enterprise
integration that covers multiple operating systems, programming languages, middleware and networking infrastructures, and
software development environments. OMG’s specifications include: UML® (Unified Modeling Language™); CORBA®
(Common Object Request Broker Architecture); CWM™ (Common Warehouse Metamodel); and industry-specific standards
for dozens of vertical markets.
More information on the OMG is available at http://www.omg.org/.
OMG Specifications
As noted, OMG specifications address middleware, modeling, and vertical domain frameworks. A listing of all OMG
Specifications is available from the OMG website at:
http://www.omg.org/spec
All of OMG’s formal specifications may be downloaded without charge from our website. (Products implementing OMG
specifications are available from individual suppliers.) Copies of specifications, available in PostScript and PDF format, may
be obtained from the Specifications Catalog cited above or by contacting the Object Management Group, Inc. at:
OMG Headquarters
109 Highland Avenue
Needham, MA 02494
USA
Tel: +1-781-444-0404
Fax: +1-781-444-0320
Email: [email protected]
Certain OMG specifications are also available as ISO standards. Please consult http://www.iso.org
Issues
The reader is encouraged to report any technical or editing issues/problems with this specification to
http://issues.omg.org/issues/create-new-issue
IDL, v4.2 v
1 Scope
This document specifies the OMG Interface Definition Language (IDL). IDL is a descriptive language used to define
data types and interfaces in a way that is independent of the programming language or operating system/processor
platform.
The IDL specifies only the syntax used to define the data types and interfaces. It is normally used in connection with
other specifications that further define how these types/interfaces are utilized in specific contexts and platforms:
• Separate “language mapping” specifications define how the IDL-defined constructs map to specific
programming languages, such as, C/C++, Java, C#, etc.
• Separate “serialization” specifications define how data objects and method invocations are serialized into a
format suitable for network transmission.
• Separate “middleware” specifications, such as, DDS or CORBA leverage the IDL to define data-types,
services, and interfaces.
The description of IDL grammar uses a syntax notation that is similar to Extended Backus-Naur Format (EBNF).
IDL, v4.2 1
2 IDL, v4.2
2 Conformance Criteria
This document defines IDL such that it can be referenced by other specifications. It contains no independent
conformance points. It is up to the specifications that depend on this document to define their own conformance
criteria. However, the general organization of the clauses (by means of atomic building blocks and profiles that group
them) is intended to ease conformance description and scoping. That means that no specification using IDL 4.0 will be
forced to be compliant with IDL constructs that are not relevant in its usage of IDL.
IDL, v4.2 3
4 IDL, v4.2
3 Normative References
The following referenced documents are indispensable for the application of this document. For dated references, only
the edition cited applies. For undated references, the latest edition of the referenced document (including any
amendments):
• ISO/IEC 14882:2003, Information Technology - Programming languages - C++.
• [RFC2119] IETF RFC 2119, "Key words for use in RFCs to Indicate Requirement Levels", S. Bradner, March
1997. Available from http://ietf.org/rfc/rfc2119.
• [CORBA] Common Object Request Broker Architecture. OMG specification: formal/2012-11-12 (part1),
formal/2012-11-14 (part2), formal/2012-11-16 (part3).
IDL, v4.2 5
6 IDL, v4.2
4 Terms and Definitions
In this specification:
• A building block is a consistent set of IDL rules that together form a piece of IDL functionality. Building blocks
are atomic, meaning that if selected, they must be totally supported. Building blocks are described in clause
7,IDL Syntax and Semantics.
• A group of annotations is a consistent set of annotations, expressed in IDL. Groups of annotations are described
in clause 8, Standardized Annotations.
• A profile is a selection of building blocks possibly complemented with groups of annotations that determines a
specific IDL usage. Profiles are described in clause 9, Profiles.
IDL, v4.2 7
8 IDL, v4.2
5 Symbols
The following acronyms are used in this specification.
Acronym Meaning
IDL, v4.2 9
10 IDL, v4.2
6 Additional Information
6.1 Acknowledgments
The following companies submitted this specification:
• Thales
• RTI
This document completes the definition of IDL as a separate specification, an effort started with IDL 3.5.
IDL 3.5 gathered in a single document all the CORBA-dedicated IDL, formerly specified as a collection of chapters
within the CORBA 3 specification.
IDL 4.0 extended that corpus with the other source for IDL definitions, namely “Extensible and Dynamic Topic Types
for DDS” in order to group all IDL constructs in a single comprehensive document. It organized the IDL description
into modular “Building Blocks” so that different levels of compliance are easier to specify and that future evolutions, if
needed, can be made without side-effects on existing IDL usages.
IDL 4.1 improved the definition of the bitset type, added a bitmap type, and resolved some inconsistencies in the
grammar.
IDL 4.2 added support for 8-bit integer types, added size-explicit keywords for integer types, enhanced the readability,
and reordered the building blocks to follow a logical dependency progression.
IDL, v4.2 11
12 IDL, v4.2
7 IDL Syntax and Semantics
7.1 Overview
This clause describes OMG Interface Definition Language (IDL) middleware 1-agnostic semantics 2 and defines the
syntax for IDL grammatical constructs.
OMG IDL is a language that allows unambiguous specification of the interfaces that client objects 3 may use and
(server) object implementations provide as well as all needed related constructs such as exceptions and data types. Data
types are needed to specify parameters and return value of interfaces' operations. They can be used also as first class
constructs.
IDL is a purely descriptive language. This means that actual programs that use these interfaces or create the associated
data types cannot be written in IDL, but in a programming language, for which mappings from IDL constructs have
been defined. The mapping of IDL constructs to a programming language will depend on the facilities available in that
programming language. For example, an IDL exception might be mapped to a structure in a language that has no
notion of exceptions, or to an exception in a language that does. The binding of IDL constructs to several programming
languages is described in separate specifications.
IDL-specific pragmas may appear anywhere in a specification; the textual location of these pragmas may be
semantically constrained by a particular implementation.
A source file containing specifications written in IDL shall have a ".idl" extension.
The description of IDL grammar uses a syntax notation that is similar to Extended Backus-Naur Format (EBNF).
However, to allow composition of specific parts of the description, while avoiding redundancy; a new operator (::+)
has been added. This operator allows adding alternatives to an existing definition. For example, assuming the rule x ::=
y, the rule x ::+ z shall be interpreted as x ::= y | z.
1
In this document the word middleware refers to any piece of software that will make use of IDL-derived artifacts. CORBA and
DDS implementations are examples of middleware. The word compiler refers to any piece of software that produces these IDL-
derived artifacts based on an IDL specification.
2
I.e., abstract semantics that is applicable to all IDL usages. When needed, middleware-specific interpretations of that abstract
semantics will be given afterwards in dedicated clauses.
3
Accordingly, client objects should be understood here as abstract clients, i.e., entities invoking operations provided by object
implementations, regardless of the means used to perform this invocation or even whether those implementations are co-located
or remotely accessible.
IDL, v4.2 13
Table 7-1 lists the symbols used in this EBNF format and their meaning.
Symbol Meaning
::= Is defined to be (left part of the rule is defined to be right part of the rule)
| Alternatively
::+ Is added as alternative (left part of the rule is completed with right part of the
rule as a new alternative)
<text> Nonterminal
"text" Literal
* The preceding syntactic unit can be repeated zero or more times
+ The preceding syntactic unit must be repeated at least once
{} The enclosed syntactic units are grouped as a single syntactic unit
[] The enclosed syntactic unit is optional – may occur zero or one time
An IDL specification logically consists of one or more files. A file is conceptually translated in several phases.
The first phase is preprocessing, which performs file inclusion and macro substitution. Preprocessing is controlled by
directives introduced by lines having # as the first character other than white space. The result of preprocessing is a
sequence of tokens. Such a sequence of tokens, that is, a file after preprocessing, is called a translation unit.
IDL uses the ASCII character set, except for string literals and character literals, which use the ISO Latin-1 (8859-1)
character set. The ISO Latin-1 character set is divided into alphabetic characters (letters) digits, graphic characters, the
space (blank) character, and formatting characters. Table 7-2 shows the ISO Latin-1 alphabetic characters; upper and
lower case equivalences are paired. The ASCII alphabetic characters are shown in the left-hand column of Table 7-2.
4
This sub clause is an adaptation of The Annotated C++ Reference Manual, Clause 2; it differs in the list of legal keywords and
punctuation
14 IDL, v4.2
Char. Description Char. Description
Dd Upper/Lower-case D Ãã Upper/Lower-case A with tilde
Ee Upper/Lower-case E Ää Upper/Lower-case A with dieresis
Ff Upper/Lower-case F Åå Upper/Lower-case A with ring above
Gg Upper/Lower-case G Ææ Upper/Lower-case dipthong A with E
Hh Upper/Lower-case H Çç Upper/Lower-case C with cedilla
Ii Upper/Lower-case I Èè Upper/Lower-case E with grave accent
Jj Upper/Lower-case J Éé Upper/Lower-case E with acute accent
Kk Upper/Lower-case K Êê Upper/Lower-case E with circumflex accent
Ll Upper/Lower-case L Ëë Upper/Lower-case E with dieresis
Mm Upper/Lower-case M Ìì Upper/Lower-case I with grave accent
Nn Upper/Lower-case N Íí Upper/Lower-case I with acute accent
Oo Upper/Lower-case O Îî Upper/Lower-case I with circumflex accent
Pp Upper/Lower-case P Ïï Upper/Lower-case I with dieresis
Qq Upper/Lower-case Q Ññ Upper/Lower-case N with tilde
Rr Upper/Lower-case R Òò Upper/Lower-case O with grave accent
Ss Upper/Lower-case S Óó Upper/Lower-case O with acute accent
Tt Upper/Lower-case T Ôô Upper/Lower-case O with circumflex accent
Uu Upper/Lower-case U Õõ Upper/Lower-case O with tilde
Vv Upper/Lower-case V Öö Upper/Lower-case O with dieresis
Ww Upper/Lower-case W Øø Upper/Lower-case O with oblique stroke
Xx Upper/Lower-case X Ùù Upper/Lower-case U with grave accent
Yy Upper/Lower-case Y Úú Upper/Lower-case U with acute accent
Zz Upper/Lower-case Z Ûû Upper/Lower-case U with circumflex accent
Üü Upper/Lower-case U with dieresis
ß Lower-case German sharp S
ÿ Lower-case Y with dieresis
IDL, v4.2 15
Table 7-4 shows the graphic characters.
16 IDL, v4.2
Char. Description Char. Description
{ left curly bracket ½ vulgar fraction 1/2
| vertical line ¾ vulgar fraction 3/4
} right curly bracket ¿ inverted question mark
~ tilde × multiplication sign
÷ division sign
backspace BS 010
7.2.1 Tokens
There are five kinds of tokens: identifiers, keywords, literals, operators, and other separators.
Blanks, horizontal and vertical tabs, newlines, form feeds, and comments (collective, "white space") as described
below are ignored except as they serve to separate tokens. Some white space is required to separate otherwise adjacent
identifiers, keywords, and constants.
If the input stream has been parsed into tokens up to a given character, the next token is taken to be the longest string
of characters that could possibly constitute a token.
7.2.2 Comments
The characters /* start a comment, which terminates with the characters */. These comments do not nest.
The characters // start a comment, which terminates at the end of the line on which they occur.
The comment characters //, /*, and */ have no special meaning within a // comment and are treated just like other
characters. Similarly, the comment characters // and /* have no special meaning within a /* comment.
IDL, v4.2 17
Comments may contain alphabetic, digit, graphic, space, horizontal tab, vertical tab, form feed, and newline characters.
7.2.3 Identifiers
An identifier is an arbitrarily long sequence of ASCII alphabetic, digit and underscore (_) characters. The first
character must be an ASCII alphabetic character. All characters are significant.
IDL identifiers are case insensitive. However, all references to a definition must use the same case as the defining
occurrence. This allows natural mappings to case-sensitive languages.
Identifiers that differ only in case collide, and will yield a compilation error under certain circumstances. An identifier
for a given definition must be spelled identically (e.g., with respect to case) throughout a specification.
There is only one namespace for IDL identifiers in each scope. Using the same identifier for a constant and an
interface, for example, produces a compilation error.
Example:
module M {
typedef long Foo;
const long thing = 1;
interface thing { // Error: reuse of identifier thing
void doit (
in Foo foo // Error: Foo and foo collide…
); // … and refer to different things
readonly attribute long Attribute; // Error: Attribute collides with keyword…
// … attribute
};
};
As all languages, IDL uses some reserved words called keywords (see 7.2.4, Keywords).
As IDL evolves, new keywords that are added to the IDL language may inadvertently collide with identifiers used in
existing IDL and programs that use that IDL. Fixing these collisions will require not only the IDL to be modified, but
programming language code that depends upon that IDL will have to change as well. The language mapping rules for
the renamed IDL identifiers will cause the mapped identifier names (e.g., method names) to be changed.
To minimize the amount of work, users may lexically "escape" identifiers by prepending an underscore (_) to an
identifier. This is a purely lexical convention that ONLY turns off keyword checking. The resulting identifier follows all
the other rules for identifier processing. For example, the identifier _AnIdentifier is treated as if it were AnIdentifier.
18 IDL, v4.2
Example:
module M {
interface thing {
attribute boolean abstract; // Error: abstract collides with keyword abstract
attribute boolean _abstract; // OK: abstract is an identifier
};
};
Note – To avoid unnecessary confusion for readers of IDL, it is recommended that IDL specifications only use the
escaped form of identifiers when the non-escaped form clashes with a newly introduced IDL keyword. It is also
recommended that interface designers avoid defining new identifiers that are known to require escaping. Escaped
literals are only recommended for IDL that expresses legacy items, or for IDL that is mechanically generated.
7.2.4 Keywords
The identifiers listed in Table 7-6 are reserved for use as keywords and may not be used for another purpose, unless
escaped with a leading underscore.
Keywords must be written exactly as shown in the above list. Identifiers that collide with keywords (see 7.2.3,
Identifiers) are illegal. For example, boolean is a valid keyword; Boolean and BOOLEAN are illegal identifiers.
IDL, v4.2 19
Example:
module M {
typedef Long Foo; // Error: keyword is long not Long
typedef boolean BOOLEAN; // Error: BOOLEAN collides with the keyword…
// …boolean;
};
Note – As the IDL grammar is now organized in building blocks that dedicated profiles may include or not, some of
these keywords may be irrelevant to some profiles. Each building block description (see 7.4, IDL Grammar) includes
the set of keywords that are specific to it. The minimum set of keywords for a given profile results from the union of
all the ones of the included building blocks. However, to avoid unnecessary confusion for readers of IDL and to allow
IDL compilers supporting several profiles in a single tool, it is recommended that IDL specifications avoid using any
of the keywords listed in Table 7-6: All IDL keywords.
In addition, the tokens listed in Table 7-8 are used by the preprocessor.
7.2.6 Literals
An integer literal consisting of a sequence of digits is taken to be decimal (base ten) unless it begins with 0 (digit zero).
A sequence of digits starting with 0 is taken to be an octal integer (base eight). The digits 8 and 9 are not octal digits and
thus are not allowed in an octal integer literal.
20 IDL, v4.2
A sequence of digits preceded by 0x (or 0X) is taken to be a hexadecimal integer (base sixteen). The hexadecimal digits
include a (or A) through f (or F) with decimal values ten through fifteen, respectively.
For example, the number twelve can be written 12, 014, or 0XC.
Character literals may have type char (non-wide character) or wchar (wide character).
Both wide and non-wide character literals must be specified using characters from the ISO Latin-1 (8859-1) character
set.
A char is an 8-bit quantity with a numerical value between 0 and 255 (decimal). The value of a space, alphabetic, digit,
or graphic character literal is the numerical value of the character as defined in the ISO Latin-1 (8859-1) character set
standard (see Table 7-2 on page 14, Table 7-3 on page 15 and Table 7-4 on page 16). The value of a null is 0. The
value of a formatting character literal is the numerical value of the character as defined in the ISO 646 standard (see
Table 7-5 on page 17). The meaning of all other characters is implementation-dependent.
A wchar (wide character) is intended to encode wide characters from any character set. Its size is implementation
dependent.
Attempts to assign a wide character literal to a non-wide character constant, or to assign a non-wide character literal to
a wide character constant, shall be treated as an error.
Nongraphic characters shall be represented using escape sequences as defined below in Table 7-9. Note that escape
sequences shall be used to represent single quote and backslash characters in character literals.
horizontal tab \t
vertical tab \v
backspace \b
carriage return \r
form feed \f
IDL, v4.2 21
Description Escape Sequence
alert \a
backslash \\
question mark \?
If the character following a backslash is not one of those specified, the behavior is undefined. An escape sequence
specifies a single character.
The escape \ooo consists of the backslash followed by one, two, or three octal digits that are taken to specify the value
of the desired character. The escape \xhh consists of the backslash followed by x followed by one or two hexadecimal
digits that are taken to specify the value of the desired character.
A sequence of octal or hexadecimal digits is terminated by the first character that is not an octal digit or a hexadecimal
digit, respectively. The value of a character constant is implementation dependent if it exceeds that of the largest char.
The escape \uhhhh consists of a backslash followed by the character u, followed by one, two, three, or four hexadecimal
digits. This represents a Unicode character literal. For example, the literal \u002E represents the Unicode period ‘.’
character and the literal \u3BC represents the Unicode Greek small letter ‘µ’ (mu). The \u escape is valid only with
wchar and wstring types. Because a wide string literal is defined as a sequence of wide character literals, a sequence
of \u literals can be used to define a wide string literal.
Attempts to set a char type to a \u defined literal or a string type to a sequence of \u literals result in an error.
Strings are null-terminated sequences of characters. Strings are of type string if they are made of non-wide characters
or wstring (wide string) if they are made of wide characters.
A string literal is a sequence of character literals (as defined in 7.2.6.2, Character Literals), with the exception of the
character with numeric value 0, surrounded by double quotes, as in:
const string S1 = "Hello";
Both wide and non-wide string literals must be specified using characters from the ISO Latin-1 (8859-1) character set.
A string literal shall not contain the character ‘\0’. A wide string literal shall not contain the wide character with value
zero.
22 IDL, v4.2
Adjacent string literals are concatenated. Characters in concatenated strings are kept distinct. For example, "\xA" "B"
contains the two characters ‘\xA’ and ‘B’ after concatenation (and not the single hexadecimal character ‘\xAB’).
The size of a string literal is the number of character literals enclosed by the quotes, after concatenation. Within a
string, the double quote character " must be preceded by a \.
Attempts to assign a wide string literal to a non-wide string constant or to assign a non-wide string literal to a wide
string constant result in a compile-time diagnostic.
A floating-point literal consists of an integer part, a decimal point (.), a fraction part, an e or E, and an optionally
signed integer exponent. The integer and fraction parts both consist of a sequence of decimal (base ten) digits. Either
the integer part or the fraction part (but not both) may be missing; either the decimal point or the letter e (or E) and the
exponent (but not both) may be missing.
A fixed-point decimal literal consists of an integer part, a decimal point (.), a fraction part and a d or D. The integer and
fraction parts both consist of a sequence of decimal (base 10) digits. Either the integer part or the fraction part (but not
both) may be missing; the decimal point (but not the letter d or D) may be missing.
7.3 Preprocessing
IDL shall be preprocessed according to the specification of the preprocessor in ISO/IEC 14882:2003. The preprocessor
may be implemented as a separate process or built into the IDL compiler.
Lines beginning with # (also called "directives") communicate with this preprocessor. White space may appear before
the #. These lines have syntax independent of the rest of IDL; they may appear anywhere and have effects that last
(independent of the IDL scoping rules) until the end of the translation unit. The textual location of IDL-specific
pragmas may be semantically constrained.
A preprocessing directive (or any line) may be continued on the next line in a source file by placing a backslash
character (\), immediately before the newline at the end of the line to be continued. The preprocessor effects the
continuation by deleting the backslash and the newline before the input sequence is divided into tokens. A backslash
character may not be the last character in a source file.
A preprocessing token is an IDL token (see 7.2.1, Tokens), a file name as in a #include directive, or any single
character other than white space that does not match another preprocessing token.
The primary use of the preprocessing facilities is to include definitions from other IDL specifications. Text in files
included with a #include directive is treated as if it appeared in the including file.
Note – Generating code for included files is an IDL compiler implementation-specific issue. To support separate
compilation, IDL compilers may not generate code for included files, or do so only if explicitly instructed.
IDL, v4.2 23
7.4 IDL Grammar
The grammar for a well-formed IDL specification is described by rules expressed in Extended Backus Naur Form
(EBNF) completed to support rule extensions as explained in clause 7.1. Table 7-1: IDL EBNF gathers all the symbols
used in rules.
These rules are grouped in atomic building blocks that will be themselves grouped to form dedicated profiles. Atomic
means that they cannot be split (in other words a given profile will contain or not a given building block, but never just
parts of it).
In all the building block descriptions, the normative rules are grouped in a sub clause entitled "Syntax" and written in
Arial bold. They are then detailed in a sub clause entitled "Explanations and Semantics", where they are copied to ease
understanding. These copies are actually hyperlinks to the originals and are written in Arial bold-italics.
In all the rules, the following non-terminals pre-exist and are not detailed.
7.4.1.1 Purpose
This building block constitutes the core of any IDL specialization (all other building blocks assume that this one is
included). It contains the syntax rules that allow defining most data types and the syntax rules that allow IDL basic
structuring (i.e., modules). Since it is the only mandatory building block, it also contains the root nonterminal
<specification> for the grammar itself.
24 IDL, v4.2
7.4.1.2 Dependencies with other Building Blocks
This building block is the root for all other building blocks and requires no other ones.
7.4.1.3 Syntax
IDL, v4.2 25
(16) <primary_expr> ::= <scoped_name>
| <literal>
| "(" <const_expr> ")"
(17) <literal> ::= <integer_literal>
| <floating_pt_literal>
| <fixed_pt_literal>
| <character_literal>
| <wide_character_literal>
| <boolean_literal>
| <string_literal>
| <wide_string_literal>
(18) <boolean_literal> ::= "TRUE"
| "FALSE"
(19) <positive_int_const> ::= <const_expr>
(20) <type_dcl> ::= <constr_type_dcl>
| <native_dcl>
| <typedef_dcl>
(21) <type_spec> ::= <simple_type_spec>
(22) <simple_type_spec> ::= <base_type_spec>
| <scoped_name>
(23) <base_type_spec> ::= <integer_type>
| <floating_pt_type>
| <char_type>
| <wide_char_type>
| <boolean_type>
| <octet_type>
(24) <floating_pt_type> ::= "float"
| "double"
| "long" "double"
(25) <integer_type> ::= <signed_int>
| <unsigned_int>
(26) <signed_int> ::= <signed_short_int>
| <signed_long_int>
| <signed_longlong_int>
(27) <signed_short_int> ::= "short"
(28) <signed_long_int> ::= "long"
(29) <signed_longlong_int> ::= "long" "long"
(30) <unsigned_int> ::= <unsigned_short_int>
| <unsigned_long_int>
| <unsigned_longlong_int>
(31) <unsigned_short_int> ::= "unsigned" "short"
(32) <unsigned_long_int> ::= "unsigned" "long"
(33) <unsigned_longlong_int> ::= "unsigned" "long" "long"
(34) <char_type> ::= "char"
(35) <wide_char_type> ::= "wchar"
(36) <boolean_type> ::= "boolean"
(37) <octet_type> ::= "octet"
26 IDL, v4.2
(38) <template_type_spec> ::= <sequence_type>
| <string_type>
| <wide_string_type>
| <fixed_pt_type>
(39) <sequence_type> ::= "sequence" "<" <type_spec> "," <positive_int_const> ">"
| "sequence" "<" <type_spec> ">"
(40) <string_type> ::= "string" "<" <positive_int_const> ">"
| "string"
(41) <wide_string_type> ::= "wstring" "<" <positive_int_const> ">"
| "wstring"
(42) <fixed_pt_type> ::= "fixed" "<" <positive_int_const> "," <positive_int_const> ">"
(43) <fixed_pt_const_type> ::= "fixed"
(44) <constr_type_dcl> ::= <struct_dcl>
| <union_dcl>
| <enum_dcl>
(45) <struct_dcl> ::= <struct_def>
| <struct_forward_dcl>
(46) <struct_def> ::= "struct" <identifier> "{" <member>+ "}"
(47) <member> ::= <type_spec> <declarators> ";"
(48) <struct_forward_dcl> ::= "struct" <identifier>
(49) <union_dcl> ::= <union_def>
| <union_forward_dcl>
(50) <union_def> ::= "union" <identifier> "switch" "(" <switch_type_spec> ")"
"{" <switch_body> "}"
(51) <switch_type_spec> ::= <integer_type>
| <char_type>
| <boolean_type>
| <scoped_name>
(52) <switch_body> ::= <case>+
(53) <case> ::= <case_label>+ <element_spec> ";"
(54) <case_label> ::= "case" <const_expr> ":"
| "default" ":"
(55) <element_spec> ::= <type_spec> <declarator>
(56) <union_forward_dcl> ::= "union" <identifier>
(57) <enum_dcl> ::= "enum" <identifier>
"{" <enumerator> { "," <enumerator> } * "}"
(58) <enumerator> ::= <identifier>
(59) <array_declarator> ::= <identifier> <fixed_array_size>+
(60) <fixed_array_size> ::= "[" <positive_int_const> "]"
(61) <native_dcl> ::= "native" <simple_declarator>
(62) <simple_declarator> ::= <identifier>
(63) <typedef_dcl> ::= "typedef" <type_declarator>
IDL, v4.2 27
(64) <type_declarator> ::= { <simple_type_spec>
| <template_type_spec>
| <constr_type_dcl>
} <any_declarators>
(65) <any_declarators> ::= <any_declarator> { "," <any_declarator> }*
(66) <any_declarator> ::= <simple_declarator>
| <array_declarator>
(67) <declarators> ::= <declarator> { "," <declarator> }*
(68) <declarator> ::= <simple_declarator>
In this building block, supported definitions are: module definitions, constant definitions and (data) type definitions as
expressed in the following rule:
(2) <definition> ::= <module_dcl> ";"
| <const_dcl> ";"
| <type_dcl> ";"
7.4.1.4.2 Modules
For more details on scoping rules, see 7.5, Names and Scoping.
An IDL module can be reopened, which means that when a module declaration is encountered with a name already
given to an existing module, all the enclosed definitions are appended to that existing module: the two module
statements are thus considered as subsequent parts of the same module description.
28 IDL, v4.2
7.4.1.4.3 Constants
IDL, v4.2 29
According to those rules, a constant is defined by:
• The const keyword.
• A type declaration, which shall denote a type suitable for a constant (<const_type>), i.e.,:
• Either one of the following: <integer_type>, <floating_pt_type>, <fixed_pt_const_type>, <char_type>,
<wide_char_type>, <boolean_type>, <octet_type>, <string_type>, <wide_string_type>, or a previously
defined enumeration. For a definition of those types, see 7.4.1.4.4, Data Types.
• Or a <scoped_name>, which shall be a previously defined name of one of the above.
• The name given to the constant (<identifier>).
• The operator =.
• A value expression (<const_expr>), which shall be consistent with the type declared for the constant.
For evaluating the value expression (right hand side of the constant declaration), the following rules shall be applied:
• If the type of an integer constant is long or unsigned long, then each sub-expression of the associated
constant expression is treated as an unsigned long by default, or a signed long for negated literals or negative
integer constants. It is an error if any sub-expression values exceed the precision of the assigned type (long or
unsigned long), or if a final expression value (of type unsigned long) exceeds the precision of the target type
(long).
• If the type of an integer constant is long long or unsigned long long, then each sub-expression of the
associated constant expression is treated as an unsigned long long by default, or a signed long long for
negated literals or negative integer constants. It is an error if any sub-expression values exceed the precision of
the assigned type (long long or unsigned long long), or if a final expression value (of type unsigned long
long) exceeds the precision of the target type (long long).
• If the type of a floating-point constant is double, then each sub-expression of the associated constant expression
is treated as a double. It is an error if any sub-expression value exceeds the precision of double.
• If the type of a floating-point constant is long double, then each sub-expression of the associated constant
expression is treated as a long double. It is an error if any sub-expression value exceeds the precision of long
double.
• An infix operator may combine two integer types, floating point types or fixed point types, but not mixtures of
these. Infix operators shall be applicable only to integer, floating point, and fixed point types.
• Integer expressions shall be evaluated based on the type of each argument of a binary operator in turn. If either
argument is unsigned long long, it shall use unsigned long long. If either argument is long long, it shall use
long long. If either argument is unsigned long, it shall use unsigned long. Otherwise it shall use long. The
final result of an integer arithmetic expression shall fit in the range of the declared type of the constant;
otherwise it shall be treated as an error. In addition to the integer types, the final result of an integer arithmetic
expression may be assigned to an octet constant, subject to it fitting in the range for octet type.
• Floating point expressions shall be evaluated based on the type of each argument of a binary operator in turn. If
either argument is long double, it shall use long double. Otherwise it shall use double. The final result of a
floating point arithmetic expression shall fit in the range of the declared type of the constant; otherwise it shall
be treated as an error.
• Fixed-point decimal constant expressions shall be evaluated as follows. A fixed-point literal has the apparent
number of total and fractional digits. For example, 0123.450d is considered to be fixed<7,3> and 3000.00d is
fixed<6,2>. Prefix operators do not affect the precision; a prefix + is optional, and does not change the result.
The upper bounds on the number of digits and scale of the result of an infix expression, fixed<d1 ,s1> op
fixed<d2,s2>, are shown in the following table.
30 IDL, v4.2
Table 7-11: Operations on fixed-point decimal constants
Op Result: fixed<d,s>
+ fixed<max(d1-s1,d2-s2) + max(s1,s2) + 1, max(s1,s2)>
- fixed<max(d1-s1,d2-s2) + max(s1,s2) + 1, max(s1,s2)>
* fixed<d1+d2, s1+s2>
/ fixed<(d1-s1+s2) + sinf , sinf>
• A quotient may have an arbitrary number of decimal places, denoted by a scale of sinf. The computation
proceeds pairwise, with the usual rules for left-to-right association, operator precedence, and parentheses. All
intermediate computations shall be performed using double precision (i.e., 62 digits) arithmetic. If an individual
computation between a pair of fixed-point literals actually generates more than 31 significant digits, then a 31-
digit result is retained as follows:
fixed<d,s> => fixed<31, 31-d+s>
• Leading and trailing zeros shall not be considered significant. The omitted digits shall be discarded; rounding shall
not be performed. The result of the individual computation then proceeds as one literal operand of the next pair
of fixed-point literals to be computed.
• Unary (+ -) and binary (* / + -) operators shall be applicable in floating-point and fixed-point expressions.
• The + unary operator shall have no effect; the – unary operator indicates that the sign of the following
expression is inverted.
• The * binary operator indicates that the two operands shall be multiplied; the / binary operator indicates that
the first operand shall be divided by the second one; the + binary operator indicates that the two operands
shall be added; the – binary operator indicates that the second operand shall be subtracted from the first
one.
• Unary (+ - ~) and binary (* / % + - << >> & | ^) operators are applicable in integer expressions.
• The + unary operator shall have no effect; the – unary operator indicates that the sign of the following
expression is inverted.
• The * binary operator indicates that the two operands shall be multiplied; the / binary operator indicates that
the first operand shall be divided by the second one; the + binary operator indicates that the two operands
shall be added; the – binary operator indicates that the second operand shall be subtracted from the first
one.
• The ~ unary operator indicates that the bit-complement of the expression to which it is applied shall be
generated. For the purposes of such expressions, the values are 2’s complement numbers. As such, the
complement can be generated as follows:
IDL, v4.2 31
Integer Constant Expression Generated 2’s Complement
Type Numbers
unsigned long long unsigned long (2**64-1) - value
• The % binary operator yields the remainder from the division of the first expression by the second. If the
second operand of % is 0, the result is undefined; otherwise (a/b)*b + a%b is equal to a.
If both operands are non-negative, then the remainder is non-negative; if not, the sign of the remainder is
implementation dependent.
• The << binary operator indicates that the value of the left operand shall be shifted left the number of bits
specified by the right operand, with 0 fill for the vacated bits. The right operand shall be in the range 0 <=
right operand < 64.
• The >> binary operator indicates that the value of the left operand shall be shifted right the number of bits
specified by the right operand, with 0 fill for the vacated bits. The right operand shall be in the range 0 <=
right operand < 64.
• The & binary operator indicates that the logical, bitwise AND of the left and right operands shall be
generated.
• The | binary operator indicates that the logical, bitwise OR of the left and right operands shall be generated.
• The ^ binary operator indicates that the logical, bitwise EXCLUSIVE-OR of the left and right operands shall
be generated.
• <positive_int_const> shall evaluate to a positive integer constant.
The consistency rules between the value (right hand side of the constant declaration) and the constant type declaration
(left hand side) are as follows:
• Integer literals have positive integer values. Constant integer literals shall be considered unsigned long unless
the value is too large, then they shall be considered unsigned long long. Unary minus shall be considered an
operator, not a part of an integer literal. Only integer values can be assigned to integer type (short, long, long
long) constants, and octet constants. Only positive integer values can be assigned to unsigned integer type
constants. If the value of an integer constant declaration is too large to fit in the actual type of the constant on
the left hand side (for example const short s = 655592;) or is inappropriate for the actual type of the constant
(for example const octet o = -54;) it shall be treated as an error.
• Octet literals have integer value in the range 0…255. If the right hand side of an octet constant declaration is
outside this range, it shall be treated as an error.
• An octet constant can be defined using an integer literal or an integer constant expression but values outside the
range 0…255 shall be treated as an error.
• Floating point literals have floating point values. Only floating point values can be assigned to floating point
type (float, double, long double) constants. Constant floating point literals are considered double unless the
value is too large, then they are considered long double. If the value of the right hand side is too large to fit in
the actual type of the constant to which it is being assigned, it shall be treated as an error. Truncation on the
right for floating point types is OK.
• Fixed point literals have fixed point values. Only fixed point values can be assigned to fixed point type constants.
If the fixed point value in the expression on the right hand side is too large to fit in the actual fixed point type of
the constant on the left hand side, then it shall be treated as an error. Truncation on the right for fixed point
types is OK.
32 IDL, v4.2
• An enum constant can only be defined using a scoped name for the enumerator. The scoped name is resolved
using the normal scope resolution rules (see 7.5, Names and Scoping). For example:
enum Color { red, green, blue };
const Color FAVORITE_COLOR = red;
module M {
enum Size { small, medium, large };
};
const M::Size MYSIZE = M::medium;
• The constant name for the value of an enumerated constant definition shall denote one of the enumerators
defined for the enumerated type of the constant. For example:
const Color col = red; // is OK but
const Color another = M::medium; // is an error
A data type may be either a simple type or a constructed one. Those different kinds are detailed in the following
clauses.
Type declarations may reference other types. These type references can be split in several categories:
• References to basic types representing primitive builtin types such as numbers and characters. These use the
keyword that identifies the type.
• References to types explicitly constructed or explictly named types. These use the scoped name of the type.
• References to anonymous template types that must be instantiated with a length (e.g. strings) or a length and an
element type (e.g. sequences).
Note – Within this building block, anonymous types, that is, the type resulting from an instantiation of a template type
(see Building Block Anonymous Types) cannot be used directly. Instead, prior to any use, template types must be
given a name through a typedef declaration. Therefore, as expressed in the following rules, referring to a simple type
can be done either using directly its name, if it is a basic type, or using a scoped name, in all other cases:
(21) <type_spec> ::= <simple_type_spec>
(22) <simple_type_spec> ::= <base_type_spec>
| <scoped_name>
Basic types are pre-existing types that represent numbers or characters. The set of basic types is defined by the
following rules:
(23) <base_type_spec> ::= <integer_type>
| <floating_pt_type>
| <char_type>
| <wide_char_type>
| <boolean_type>
| <octet_type>
IDL, v4.2 33
(24) <floating_pt_type> ::= "float"
| "double"
| "long" "double"
(25) <integer_type> ::= <signed_int>
| <unsigned_int>
(26) <signed_int> ::= <signed_short_int>
| <signed_long_int>
| <signed_longlong_int>
(27) <signed_short_int> ::= "short"
(28) <signed_long_int> ::= "long"
(29) <signed_longlong_int> ::= "long" "long"
(30) <unsigned_int> ::= <unsigned_short_int>
| <unsigned_long_int>
| <unsigned_longlong_int>
(31) <unsigned_short_int> ::= "unsigned" "short"
(32) <unsigned_long_int> ::= "unsigned" "long"
(33) <unsigned_longlong_int> ::= "unsigned" "long" "long"
(34) <char_type> ::= "char"
(35) <wide_char_type> ::= "wchar"
(36) <boolean_type> ::= "boolean"
(37) <octet_type> ::= "octet"
IDL integer types are short, unsigned short, long, unsigned long, long long, and unsigned long long representing
integer values in the range indicated below in Table 7-13.
34 IDL, v4.2
7.4.1.4.4.2.2 Floating-Point Types
IDL floating-point types are float, double, and long double. The float type represents IEEE single-precision floating
point numbers; the double type represents IEEE double-precision floating point numbers. The long double data type
represents an IEEE double-extended floating-point number, which has an exponent of at least 15 bits in length and a
signed fraction of at least 64 bits. See IEEE Standard for Binary Floating-Point Arithmetic, ANSI/IEEE Standard 754-
1985, for a detailed specification.
IDL defines a char data type that is an 8-bit quantity that (1) encodes a single-byte character from any byte-oriented
code set, or (2) when used in an array, encodes a multi-byte character from a multi-byte code set.
IDL defines a wchar data type that encodes wide characters from any character set. The size of wchar is
implementation-dependent.
The boolean data type is used to denote a data item that can only take one of the values TRUE and FALSE.
The octet type is an opaque 8-bit quantity that is guaranteed not to undergo any change by the middleware.
Template types are generic types that are parameterized by type of underlying elements and/or the number of elements.
To be used as an actual type, such a generic definition must be instantiated, i.e., given parameter values, whose nature
depends on the template type.
As specified in the following rule, template types are sequences (<sequence_type>), strings (<string_type>, wide
strings (<wide_string_type>) and fixed-point numbers (<fixed_pt_type>).
(38) <template_type_spec> ::= <sequence_type>
| <string_type>
| <wide_string_type>
| <fixed_pt_type>
7.4.1.4.4.3.1 Sequences
IDL, v4.2 35
As a template type, sequence has two parameters:
• The first non-optional parameter (<type_spec>) gives the type of each item in the sequence.
• The second optional parameter (<positive_int_const> is a positive integer constant that indicates the maximum
size of the sequence. If it is given, the sequence is termed a bounded sequence. Otherwise the sequence is said
unbounded and no maximum size is specified.
Before using a bounded or unbounded sequence, the length of the sequence must be set in a language-mapping
dependent manner. If the bounded form is used, the length must be less than or equal to the maximum. Similarly after
receiving a sequence, this value may be obtained in a language-mapping dependent manner.
7.4.1.4.4.3.2 Strings
IDL defines the string type string consisting of a list of all possible 8-bit quantities except null. A string is similar to a
sequence of char. As with sequences of any type, prior to passing a string as a function argument (or as a field in a
structure or union), the length of the string must be set in a language-mapping dependent manner. The syntax is:
(40) <string_type> ::= "string" "<" <positive_int_const> ">"
| "string"
The argument to the string declaration is the maximum size of the string (<positive_int_const>). If a positive integer
maximum size is specified, the string is termed a bounded string. If no maximum size is specified, the string is termed
an unbounded string. The actual length of a string is set at run-time and, if the bounded form is used, must be less than
or equal to the maximum.
Note – Strings are singled out as a separate type because many languages have special built-in functions or standard
library functions for string manipulation. A separate string type may permit substantial optimization in the handling of
strings compared to what can be done with sequences of general types.
7.4.1.4.4.3.3 Wstrings
The wstring data type represents a sequence of wchar, except the wide character null. The type wstring is similar to
that of type string, except that its element type is wchar instead of char. The syntax for defining a wstring is:
(41) <wide_string_type> ::= "wstring" "<" <positive_int_const> ">"
| "wstring"
The fixed data type represents a fixed-point decimal number of up to 31 significant digits. The syntax to declare a fixed
data type is:
(42) <fixed_pt_type> ::= "fixed" "<" <positive_int_const> "," <positive_int_const> ">"
The first parameter is the number of total digits (up to 31), the second one the number of fractional digits, which must
be less or equal to the former.
In case the fixed type specification is used in a constant declaration, those two parameters are omitted as they are
automatically deduced from the constant value. The syntax is thus as follows:
(43) <fixed_pt_const_type> ::= "fixed"
Note – The fixed data type will be mapped to the native fixed point capability of a programming language, if
available. If there is not a native fixed point type, then the IDL mapping for that language will provide a fixed point
36 IDL, v4.2
data type. Applications that use the IDL fixed point type across multiple programming languages must take into
account differences between the languages in handling rounding, overflow, and arithmetic precision.
As expressed in the following rule, structures (<struct_dcl>), unions (<union_dcl>) and enumerations (<enum_dcl>)
are the constructed types supported in this building block:
(44) <constr_type_dcl> ::= <struct_dcl>
| <union_dcl>
| <enum_dcl>
7.4.1.4.4.4.1 Structures
A structure is a grouping of at least one member. The syntax to declare a structure is as follows:
(45) <struct_dcl> ::= <struct_def>
| <struct_forward_dcl>
(46) <struct_def> ::= "struct" <identifier> "{" <member>+ "}"
(47) <member> ::= <type_spec> <declarators> ";"
(67) <declarators> ::= <declarator> { "," <declarator> }*
(68) <declarator> ::= <simple_declarator>
The name of a structure defines a new legal type that may be used anywhere such a type is legal in the grammar.
Note – Members may be of any data type, including sequences or arrays. However, except when anonymous types are
supported (cf. 7.4.14, Building Block Anonymous Types for more details), sequences or arrays need to be given a
name (with typedef) to be used in the member declaration.
Structures may be forward declared, in particular to allow the definition of recursive structures. Cf. 7.4.1.4.4.4.4,
Constructed Recursive Types and Forward Declarations for more details.
7.4.1.4.4.4.2 Unions
IDL unions are a cross between C unions and switch statements. They may host a value of one type to be chosen
between several possible cases. IDL unions must be discriminated: they embed a discriminator that indicates which
case is to be used for the current instance. The possible cases as well as the type of the discriminator are part of the
union declaration, whose syntax is as follows:
IDL, v4.2 37
(49) <union_dcl> ::= <union_def>
| <union_forward_dcl>
(50) <union_def> ::= "union" <identifier> "switch" "(" <switch_type_spec> ")"
"{" <switch_body> "}"
(51) <switch_type_spec> ::= <integer_type>
| <char_type>
| <boolean_type>
| <scoped_name>
(52) <switch_body> ::= <case>+
(53) <case> ::= <case_label>+ <element_spec> ";"
(54) <case_label> ::= "case" <const_expr> ":"
| "default" ":"
(55) <element_spec> ::= <type_spec> <declarator>
The name of a union defines a new legal type that may be used anywhere such a type is legal in the grammar.
It is not required that all possible values of the union discriminator be listed in the <switch_body>. The value of a
union is the value of the discriminator together with one of the following:
1. If the discriminator value was explicitly listed in a case statement, the value of the element associated with
that case statement.
2. If a default case label was specified, the value of the element associated with the default case label.
3. No additional value.
Note – Name scoping rules require that the element declarators (all the <declarator> in the different
<element_spec>) in a particular union be unique. If the <switch_type_spec> is an enumeration, the identifier for the
enumeration is as well in the scope of the union; as a result, it must be distinct from the element declarators. The values
38 IDL, v4.2
of the constant expressions for the case labels of a single union definition must be distinct. A union type can contain a
default label only where the values given in the non-default labels do not cover the entire range of the union's
discriminant type.
Note – While any ISO Latin-1 (8859-1) IDL character literal may be used in a <case_label> in a union definition
whose discriminator type is char, not all of these characters are present in all code sets that may be used by
implementation language compilers and/or runtimes, which may lead to some interoperability issue (typically leading
to a DATA_CONVERSION system exception). Therefore, to ensure portability and interoperability, care must be
exercised when assigning the <case_label> for a union member whose discriminator type is char. Due to this potential
issue, use of char types as the discriminator type for unions is not recommended.
7.4.1.4.4.4.3 Enumerations
Enumerated types (enumerations) consist of ordered lists of enumerators. The syntax to create such a type is as
follows:
(57) <enum_dcl> ::= "enum" <identifier>
"{" <enumerator> { "," <enumerator> } * "}"
(58) <enumerator> ::= <identifier>
The name of an enumeration defines a new legal type that may be used anywhere such a type is legal in the grammar.
Note – The enumerated names must be mapped to a native data type capable of representing a maximally-sized
enumeration. The order in which the identifiers are named in the specification of an enumeration defines the relative
order of the identifiers. Any language mapping that permits two enumerators to be compared or defines
successor/predecessor functions on enumerators must conform to this ordering relation.
The IDL syntax allows the generation of recursive structures and unions via members that have a sequence type. For
example, the following:
struct Foo; // Forward declaration
typedef sequence<Foo> FooSeq;
struct Foo {
long value;
FooSeq chain; // Recursive
};
The forward declaration for the structure enables the definition of the sequence type FooSeq, which is used as the type
of the recursive member.
Forward declarations are legal for structures and unions. Their syntax is as follows:
(48) <struct_forward_dcl> ::= "struct" <identifier>
IDL, v4.2 39
(56) <union_forward_dcl> ::= "union" <identifier>
A structure or union type is termed incomplete until its full definition is provided; that is, until the scope of the
structure or union definition is closed by a terminating };. For example:
struct Foo; // Introduces Foo type name,
// Foo is incomplete now
// ...
struct Foo {
// ...
}; // Foo is complete at this point
If a structure or union is forward declared, a definition of that structure or union must follow the forward declaration in
the same compilation unit. If this rule is violated it shall be treated as an error. Multiple forward declarations of the
same structure or union are legal.
If a sequence member of a structure or union refers to an incomplete type, the structure or union itself remains
incomplete until the member’s definition is completed. For example:
struct Foo;
typedef sequence<Foo> FooSeq;
struct Bar {
long value;
FooSeq chain; // Use of incomplete type
}; // Bar itself remains incomplete
struct Foo {
// ...
}; // Foo and Bar are complete
An incomplete type can only appear as the element type of a sequence definition. A sequence with incomplete element
type is termed an incomplete sequence type. For example:
struct Foo; // Forward declaration
typedef sequence<Foo> FooSeq; // Incomplete
An incomplete sequence type can appear only as the element type of another sequence, or as the member type of a
structure or union definition. If this rule is violated it shall be treated as an error.
40 IDL, v4.2
7.4.1.4.4.5 Arrays
IDL defines multidimensional, fixed-size arrays. An array includes explicit sizes for each dimension. The syntax for
arrays is very similar to the one of C or C++ as stated in the following rules:
(59) <array_declarator> ::= <identifier> <fixed_array_size>+
(60) <fixed_array_size> ::= "[" <positive_int_const> "]"
The array size (in each dimension) is fixed at compile time. The implementation of array indices is language mapping
specific.
Declaring an array with all its dimensions creates an anonymous type. Within this building block, such a type cannot
be used as is but needs to be given a name through a typedef declaration prior to any use.
IDL provides a declaration to define an opaque type whose representation is specified by the language mapping.
As stated in the following rules, declaring a native type is done prefixing the type name (<simple_declarator>) with
the native keyword:
(61) <native_dcl> ::= "native" <simple_declarator>
(62) <simple_declarator> ::= <identifier>
This declaration defines a new type with the specified name. A native type is similar to an IDL basic type. The possible
values of a native type are language-mapping dependent, as are the means for constructing and manipulating them.
Any IDL specification that defines a native type requires each language mapping to define how the native type is
mapped into that programming language.
Note – It is recommended that native types be mapped to equivalent type names in each programming language,
subject to the normal mapping rules for type names in that language.
IDL provides constructs for naming types; that is, it provides C language-like declarations that associate an identifier
with a type. The syntax for type declaration is as follows:
(63) <typedef_dcl> ::= "typedef" <type_declarator>
(64) <type_declarator> ::= { <simple_type_spec>
| <template_type_spec>
| <constr_type_dcl>
} <any_declarators>
(65) <any_declarators> ::= <any_declarator> { "," <any_declarator> }*
(66) <any_declarator> ::= <simple_declarator>
| <array_declarator>
IDL, v4.2 41
Such a declaration is made of:
• The typedef keyword.
• The type specification, which may be a simple type specification (<simple_type_spec>), that is either a basic
type or a scoped name denoting any IDL legal type, or a template type specification (<template_type_spec>),
or a declaration for a constructed type (<constr_type_dcl>).
• A list of at least one declarator, which will provide the new type name. Each declarator can be either a simple
identifier (<simple_declarator>), which will be then the name allocated to the type, or an array declarator
(<array_declarator>), in which case the new name (<identifier> enclosed within the array declarator) will
denote an array of specified type.
Note – As previously seen, a name is also associated with a data type via the struct, union, enum, and native
declarations.
Note – Within this building block where anonymous types are forbidden, a typedef declaration is needed to name,
prior to any use, an array or a template instantiation.
The following table selects in Table 7-6 the keywords that are specific to this building block and removes the others.
42 IDL, v4.2
Table 7-14: Keywords specific to Building Block Core Data Types
7.4.2.1 Purpose
This building block adds the ability to declare a type that may represent any valid data type.
7.4.2.3 Syntax
IDL, v4.2 43
7.4.2.4 Explanations and Semantics
An any is a type that may represent any valid data type. At IDL level, it is just declared with the keyword any.
An any logically contains a value and some means to specify the actual type of the value. However, the specific way in
which the actual type is defined is middleware-specific 5. Each IDL language mapping provides operations that
allow programmers to insert and access the value contained in an any as well as the actual type of that value.
The following table selects in Table 7-6 the keywords that are specific to this building block and removes the others.
5
For CORBA this means is a TypeCode (see [CORBA], Part1, Sub clause 8.11 “TypeCodes”).
44 IDL, v4.2
7.4.3 Building Block Interfaces – Basic
7.4.3.1 Purpose
This building block gathers all the rules needed to define basic interfaces, i.e., consistent groupings of operations. At
this stage, there is no other implicit behavior attached to interfaces.
7.4.3.3 Syntax
IDL, v4.2 45
(90) <readonly_attr_declarator>
::= <simple_declarator> <raises_expr>
| <simple_declarator> { "," <simple_declarator> }*
(91) <attr_spec> ::= "attribute" <type_spec> <attr_declarator>
(92) <attr_declarator> ::= <simple_declarator> <attr_raises_expr>
| <simple_declarator> { "," <simple_declarator> }*
(93) <attr_raises_expr> ::= <get_excep_expr> [ <set_excep_expr> ]
| <set_excep_expr>
(94) <get_excep_expr> ::= "getraises" <exception_list>
(95) <set_excep_expr> ::= "setraises" <exception_list>
(96) <exception_list> ::= "(" <scoped_name> { "," <scoped_name> } * ")"
With that building block, an IDL specification may declare exceptions and interfaces (that are merely groups of
operations).
(71) <definition> ::+ <except_dcl> ";"
| <interface_dcl> ";"
7.4.3.4.2 Exceptions
Exceptions are specific data structures, which may be returned to indicate that an exceptional condition has occurred
during the execution of an operation. The syntax to declare an exception is as follows:
(72) <except_dcl> ::= "exception" <identifier> "{" <member>* "}"
If an exception is returned as the outcome to an operation invocation, then the value of the exception identifier shall be
accessible to the programmer for determining which particular exception was raised.
If an exception is declared with members, a programmer shall be able to access the values of those members when such
an exception is raised. If no members are specified, no additional information shall be accessible when such an
exception is raised.
An identifier declared to be an exception identifier may appear only in a raises expression of an operation or attribute
declaration, and nowhere else.
46 IDL, v4.2
7.4.3.4.3 Interfaces
Interfaces are groupings of elements (in this building block operations and attributes).
As defined by the following rules, an interface is made of a header (<interface_header>) and a body
(<interface_body>) enclosed in braces ({}). An interface may also be declared with no definition using a forward
declaration (<interface_forward_dcl>).
(73) <interface_dcl> ::= <interface_def>
| <interface_forward_dcl>
(74) <interface_def> ::= <interface_header> "{" <interface_body> "}"
The <identifier> that names an interface defines a new legal type. Such a type may be used anywhere a type is legal in
the grammar, subject to semantic constraints as described in the following sub clauses. A parameter or structure member
which is of an interface type is semantically a reference to an object implementing that interface. Each language
binding describes how the programmer must represent such interface references.
Interface inheritance is introduced by a colon (:) and must follow the following syntax:
(78) <interface_inheritance_spec>
::= ":" <interface_name> { "," <interface_name> }*
(79) <interface_name> ::= <scoped_name>
An interface can be derived from another interface, which is then called a base interface of the derived interface. A
derived interface, like all interfaces, may declare new elements (in this building block, operations and attributes). In
addition the elements of a base interface can be referred to as if they were elements of the derived interface.
An interface is called a direct base if it is mentioned in the <interface_inheritance_spec> and an indirect base if it is
not a direct base but is a base interface of one of the interfaces mentioned in the <interface_inheritance_spec>.
IDL, v4.2 47
An interface may be derived from any number of base interfaces. Such use of more than one direct base interface is
often called multiple inheritance. The order of derivation is not significant.
An interface may not be specified as a direct base interface of a derived interface more than once; it may be an indirect
base interface more than once. Consider the following example:
interface A { ... };
interface B: A { ... };
interface C: A { ... };
interface D: B, C { ... }; // OK
interface E: A, B { ... }; // OK
The relationships between these interfaces are shown in Figure 7-1. This "diamond" shape is legal, as is the definition
of E on the right.
A A
B C B E C
D D
It is forbidden to redefine an operation or an attribute in a derived interface, as well as inheriting two different
operations or attributes with the same name.
interface A {
void make_it_so();
};
interface B: A {
short make_it_so(in long times); // Error: redefinition of make_it_so
};
As stated in the following rules, within an interface body, operations and attributes can be defined. Those constructs
are defined in the scope of the interface and exported (i.e., accessible outside the interface definition using their name
scoped by the interface name).
(80) <interface_body> ::= <export>*
(81) <export> ::= <op_dcl> ";"
| <attr_dcl> ";"
48 IDL, v4.2
Operations and attributes are detailed in the following sub clauses.
7.4.3.4.3.3.1 Operations
Operation declarations in IDL are similar to C function declarations. To define an operation, the syntax is:
(82) <op_dcl> ::= <op_type_spec> <identifier> "(" [ <parameter_dcls> ] ")" [ <raises_expr> ]
(83) <op_type_spec> ::= <type_spec>
| "void"
(84) <parameter_dcls> ::= <param_dcl> { "," <param_dcl> } *
(85) <param_dcl> ::= <param_attribute> <type_spec> <simple_declarator>
(86) <param_attribute> ::= "in"
| "out"
| "inout"
(87) <raises_expr> ::= "raises" "(" <scoped_name> { "," <scoped_name> } * ")"
It is expected that an implementation will not attempt to modify an in parameter. The ability to even attempt to do so is
language-mapping specific; the effect of such an action is undefined.
In addition to any operation-specific exceptions specified in the raises expression, other middleware-specific standard
exceptions may be raised. These exceptions are described in the related profiles.
The absence of a raises expression on an operation implies that there are no operation-specific exceptions. Invocations
of such an operation may still raise one of the middleware-specific standard exceptions.
IDL, v4.2 49
If an exception is raised as a result of an invocation, the values of the return result and any out and inout parameters
are undefined.
Note – A native type (cf. 7.4.1.4.4.6) may be used to define operation parameters, results, and exceptions. If a native
type is used for an exception, it must be mapped to a type in a programming language that can be used as an exception.
7.4.3.4.3.3.2 Attributes
Attributes may also be declared within an interface. Declaring an attribute is logically equivalent to declaring a pair of
accessor functions; one to retrieve the value of the attribute and one to set the value of the attribute.
The optional raises expressions take different forms according to the attribute kinds:
• For read-only attributes, raises expressions are similar to those of operations (cf. rule (90) above).
• For plain attributes, raises expressions indicate which of the potential user-defined exceptions may be raised
when the attribute is read (getraises) and which when the attribute is written (setraises). A plain attribute may
have a getraises expression, a setraises expression or both of them. In the latter case, the getraises expression
must be declared in first place.
The absence of a raises expression (raises, getraises or setraises) on an attribute implies that there are no attribute-
specific exceptions. Accesses to such an attribute may still raise middleware-specific standard exceptions.
50 IDL, v4.2
As a shortcut, several attributes can be declared in a single attribute declaration, provided that there are no attached
raises clauses. In that case, the names of the attributes are listed, separated by a comma (,).
Note – A native type (cf. 7.4.1.4.4.6) may be used to define attribute types, and exceptions. If a native type is used for
an exception, it must be mapped to a type in a programming language that can be used as an exception.
A forward declaration declares the name of an interface without defining it. This permits the definition of interfaces
that refer to each other.
As stated in the following rule, the syntax for a forward declaration is simply the declaration of the kind of interface 6,
followed by the interface name:
(75) <interface_forward_dcl> ::= <interface_kind> <identifier>
(77) <interface_kind> ::= "interface"
Multiple forward declarations of the same interface name are legal, provided that they are all consistent.
The following table selects in Table 7-6 the keywords that are specific to this building block and removes the others.
exception
getraises
in inout interface
6
The definition of a forward-declared interface must be consistent with the forward declaration: they must share the same
interface kind. With this building block, there is only one interface kind (namely interface) however other interface-related
building blocks will add other kinds (such as abstract interface).
IDL, v4.2 51
out
7.4.4.1 Purpose
This building block complements the former one with the ability to embed in the interface body, additional
declarations such as types, exceptions and constants.
This building block complements Building Block Interfaces – Basic. Transitively, it relies on Building Block Core
Data Types.
7.4.4.3 Syntax
This building block adds the possibility to embed declarations of types, constants and exceptions inside an interface
declaration.
The syntax for those embedded elements is exactly the same as if they were top-level constructs.
All those elements are exported (i.e., visible under the scope of their hosting interface). In contrast to attributes and
operations, they may be redefined in a derived interface, which has the following consequences:
• In a derived interface, all elements of a base class may be referred to as if they were elements of the derived
class, unless they are redefined in the derived class. The name resolution operator (::) may be used to refer to a
52 IDL, v4.2
base element explicitly; this permits reference to a name that has been redefined in the derived interface. The
scope rules for such names are described in 7.5, Names and Scoping.
• References to base interface elements must be unambiguous. A reference to a base interface element
is ambiguous if the name is declared as a constant, type, or exception in more than one base
interface. Ambiguities can be resolved by qualifying a name with its interface name (that is, using a
<scoped_name>). It is illegal to inherit from two interfaces with the same operation or attribute name, or to
redefine an operation or attribute name in the derived interface.
For example in:
interface A {
typedef long L1;
short opA (in L1 l_1);
};
interface B {
typedef short L1;
L1 opB (in long l);
};
interface C: B, A {
typedef L1 L2; // Error: L1 ambiguous
typedef A::L1 L3; // A::L1 is OK
B::L1 opC (in L3 l_3); // All OK no ambiguities
};
• References to constants, types, and exceptions are bound to an interface when it is defined (i.e., replaced with
the equivalent global scoped names). This guarantees that the syntax and semantics of an interface are not
changed when the interface is a base interface for a derived interface.
Consider the following example:
const long L = 3;
interface A {
typedef float coord[L]:
void f (in coord s); // s has three floats
};
interface B {
const long L = 4;
};
interface C: B, A { }; // What is C::f()’s signature?
The early binding of constants, types, and exceptions at interface definition guarantees that the signature of
operation f in interface C is typedef float coord[3]; void f (in coord s); which is identical to that in interface
A. This rule also prevents redefinition of a constant, type, or exception in the derived interface from affecting
the operations and attributes inherited from a base interface.
• Interface inheritance causes all identifiers defined in base interfaces, both direct and indirect, to be visible in the
current naming scope. A type name, constant name, enumeration value name, or exception name from an
enclosing scope can be redefined in the current scope. An attempt to use an ambiguous name without
qualification shall be treated as an error. Thus in:
IDL, v4.2 53
interface A {
typedef string<128> string_t;
};
interface B {
typedef string<256> string_t;
};
interface C: A, B {
attribute string_t Title; // Error: string_t ambiguous
attribute A::string_t Name; // OK
attribute B::string_t City; // OK
};
7.4.5.1 Purpose
This building block adds the ability to declare plain value types.
As opposed to interfaces which are merely groups of operations 7, values carry also state contents. A value type is, in
some sense, half way between a "regular" IDL interface type and a structure.
Value types add the following features to the expressive power of structures:
• Single derivation (from other value types).
• Single interface support.
• Arbitrary recursive value type definitions, with sharing semantics providing the ability to define lists, trees,
lattices, and more generally arbitrary graphs using value types.
• Null value semantics.
Designing a value type requires that some additional properties (state) and implementation details be specified beyond
that of an interface type. Specification of this information puts some additional constraints on the implementation
choices beyond that of interface types. This is reflected in both the semantics specified herein, and in the language
mappings.
An essential property of value types is that their implementations are always collocated with their clients. That is, the
explicit use of values in a concrete programming language is always guaranteed to use local implementations, and will
not require remote calls. They have thus no system-wide identity (their value is their identity).
7
Interface attributes are actually equivalent to accessors.
54 IDL, v4.2
7.4.5.2 Dependencies with other Building Blocks
This building block requires Building Block Interfaces – Basic. Transitively, it relies on Building Block Core Data
Types.
7.4.5.3 Syntax
With that building block, an IDL specification may additionally declare value types, as expressed in:
(98) <definition> ::+ <value_dcl> ";"
There are two kinds of value type declarations: definitions of concrete (stateful) value types, and forward declarations.
(99) <value_dcl> ::= <value_def>
| <value_forward_dcl>
Regular value types (also named concrete or stateful) are declared with the following syntax:
(100) <value_def> ::= <value_header> "{" <value_element>* "}"
A value declaration consists of a header (<value_header>) and a body, made of value elements (<value_element>*)
enclosed within braces ({}). Those constructs are detailed in the following clauses.
IDL, v4.2 55
7.4.5.4.1.1 Value Header
The name of a value type defines a new legal type that may be used anywhere such a type is legal in the grammar.
As expressed in the following rules, value types may inherit from one value type and may support one interface:
(103) <value_inheritance_spec>
::= [ ":" <value_name> ] [ "supports" <interface_name> ]
(104) <value_name> ::= <scoped_name>
The value inheritance specification is thus made of two parts (both being optional):
• The inheritance from another value type, introduced by a colon sign (:) where the <value_name> must be the
name of a previously defined value type or an alias 8 to a previously defined value type.
• The inheritance from an interface, introduced by the supports keyword, where the <interface_name> must be
the name of a previously defined interface or an alias to a previously defined interface.
A value can contain all the elements that an interface can (<export> in the following rule) as well as definitions of state
members and initializers for that state.
(105) <value_element> ::= <export>
| <state_member>
| <init_dcl>
Each <state_member> defines an element of the state, which is transmitted to the receiver when the value type is
passed as a parameter. A state member is either public or private. The annotation directs the language mapping to
expose or hide the different parts of the state to the clients of the value type. While its public part is exposed to all, the
private part of the state is only accessible to the implementation code.
8
i.e., created by a typedef declaration.
56 IDL, v4.2
Note – Some programming languages may not have the built in facilities needed to distinguish between public and
private members. In these cases, the language mapping specifies the rules that programmers are responsible for.
7.4.5.4.1.3.2 Initializers
In order to ensure portability of value implementations, designers may also define the signatures of initializers (or
constructors) for concrete value types. Syntactically these look like local operation signatures except that they are
prefixed with the keyword factory, have no return type, and must use only in parameters.
(107) <init_dcl> ::= "factory" <identifier> "(" [ <init_param_dcls> ] ")" [ <raises_expr> ] ";"
(108) <init_param_dcls> ::= <init_param_dcl> { "," <init_param_dcl>}*
(109) <init_param_dcl> ::= "in" <type_spec> <simple_declarator>
There may be any number of factory declarations. The names of the initializers are part of the name scope of the value
type. Initializers defined in a value type are not inherited by derived value types, and hence the names of the initializers
are free to be reused in a derived value type.
Similar to interfaces, value types may be forward-declared, with the following syntax:
(110) <value_forward_dcl> ::= <value_kind> <identifier>
A forward declaration declares the name of a value type without defining it. This permits the definition of value types
that refer to each other. The syntax consists simply of the keyword valuetype followed by an <identifier> that names
the value type.
Multiple forward declarations of the same value type name are legal.
It is illegal for a value type to support a forward-declared interface not previously defined.
The following table selects in Table 7-6 the keywords that are specific to this building block and removes the others.
factory
IDL, v4.2 57
private
public
supports
valuetype
7.4.6.1 Purpose
This building block adds the syntactical elements that are specific to CORBA as well as provides explanations specific
to a CORBA usage of the imported elements.
This building block is based on Building Block Interfaces – Full. Transitively, it relies on Building Block Interfaces –
Basic and Building Block Core Data Types.
7.4.6.3 Syntax
58 IDL, v4.2
(119) <interface_kind> ::+ "local" "interface"
(120) <op_oneway_dcl> ::= "oneway" "void" <identifier> "(" [ <in_parameter_dcls> ] ")"
(121) <in_parameter_dcls> ::= <in_param_dcl> { "," <in_param_dcl> } *
(122) <in_param_dcl> ::= "in" <type_spec> <simple_declarator>
(123) <op_with_context> ::= {<op_dcl> | <op_oneway_dcl>} <context_expr>
(124) <context_expr> ::= "context" "(" <string_literal> { "," <string_literal>* } ")"
All these constructs are presented in the following sub clauses as far as it is needed to understand their syntax. For
more details on their precise semantics, refer to the CORBA documentation.
A few new constructs related to the Interface Repository are parts of this building block:
(111) <definition> ::+ <type_id_dcl> ";"
| <type_prefix_dcl> ";"
| <import_dcl> ";"
(112) <export> ::+ <type_id_dcl> ";"
| <type_prefix_dcl> ";"
| <import_dcl> ";"
| <op_oneway_dcl>
IDL, v4.2 59
At most one repository identity declaration may occur for any named type definition. An attempt to redefine the
repository identity for a type definition is illegal, regardless of the value of the redefinition.
Note – "prefixed to the body of a repository identifier" means that the specified string is inserted into the default IDL
format repository identifier immediately after the format name and colon ("IDL:") at the beginning of the identifier. A
forward slash (/) character is inserted between the end of the specified string and the remaining body of the repository
identifier.
Note – The prefix is only applied to repository identifiers whose values are not explicitly assigned by a typeid
declaration. The prefix is applied to all such repository identifiers in the specified name scope, including the identifier
of the construct that constitutes the name scope.
In IDL that contains pragma prefix/ID declarations (as defined in [CORBA] , Part1, Sub clause 14.7.5 "Pragma
Directives for RepositoryId") and typeprefix/typeid declarations as explained below, both mechanisms must return the
same repository id for the same IDL element otherwise an error should be raised.
Note that this rule applies only when the repository id value computation uses explicitly declared values from
declarations of both kinds. If the repository id computed using explicitly declared values of one kind conflicts with one
computed with implicit values of the other kind, the repository id based on explicitly declared values shall prevail.
7.4.6.4.1.4 Imports
9
Assuming that those constructs are part of the current profile.
60 IDL, v4.2
The <imported_scope> non-terminal may be either a fully-qualified scoped name denoting an IDL name scope, or a
string containing the interface repository ID of an IDL name scope, i.e., a definition object in the repository whose
interface derives from CORBA::Container.
The definition of import obviates the need to define the meaning of IDL constructs in terms of "file scopes." This
standard defines the concepts of a specification as a unit of IDL expression. In the abstract, a specification consists of a
finite sequence of ISO Latin-1 (8859-1) characters that form a legal IDL sentence. The physical representation of the
specification is of no consequence to the definition of IDL, though it is generally associated with a file in practice.
Any scoped name that begins with the scope token (::) is resolved relative to the global scope of the specification in
which it is defined. In isolation, the scope token represents the scope of the specification in which it occurs.
A specification that imports name scopes must be interpreted in the context of a well-defined set of IDL specifications
whose union constitutes the space from within which name scopes are imported. A "well-defined set of IDL
specifications," means any identifiable representation of IDL specifications, such as an interface repository. The
specific representation from which name scopes are imported is not specified, nor is the means by which importing is
implemented, nor is the means by which a particular set of IDL specifications (such as an interface repository) is
associated with the context in which the importing specification is to be interpreted.
10
Assuming that these constructs are part of the current profile.
IDL, v4.2 61
7.4.6.4.2 Object
In a CORBA scope, all interfaces inherit either directly or indirectly from a common root named Object
(CORBA::Object). The IDL Object keyword allows designating that common root in any place where an interface is
allowed. This is expressed by the following additional rules:
(117) <base_type_spec> ::+ <object_type>
(118) <object_type> ::= "Object"
In a CORBA scope, interfaces are by default potentially remote interfaces. The keyword local allows declaring
interfaces that cannot be remote.
(119) <interface_kind> ::+ "local" "interface"
An interface declaration containing the keyword local in its header declares a local interface. An interface declaration
not containing the keyword local is referred to as an unconstrained interface. An object implementing a local interface
is referred to as a local object. The following special rules apply to local interfaces:
• A local interface may inherit from other local or unconstrained interfaces.
• An unconstrained interface may not inherit from a local interface. An interface derived from a local interface
must be explicitly declared local.
• A value type 11 may support a local interface.
• Any IDL type, including an unconstrained interface, may appear as a parameter, attribute, return type, or
exception declaration of a local interface.
• A local interface is a local type, as is any non-interface type declaration constructed using a local interface or
other local type. For example, a structure, union, or exception with a member that is a local interface is also
itself a local type.
• A local type may be used as a parameter, attribute, return type, or exception declaration of a local interface or of
a value type.
• A local type may not appear as a parameter, attribute, return type, or exception declaration of an unconstrained
interface.
See the [CORBA], Part1, Sub clause 8.3.14 "Local Object Operations" for CORBA implementation semantics
associated with local objects.
In a CORBA context, native type parameters are not permitted in operations of remote interfaces. Any attempt to
transmit a value of a native type in a remote invocation may raise the MARSHAL standard system exception.
Note – The native type declaration is provided specifically for use in object adapter interfaces, which require
parameters whose values are concrete representations of object implementation instances. It is strongly recommended
that it not be used in service or application interfaces. The native type declaration allows object adapters to define new
primitive types without requiring changes to the IDL language or to the IDL compiler.
11
Assuming that this construct is part of the current profile.
62 IDL, v4.2
7.4.6.4.5 One-way Operations
By default calling applications are blocked until the called operations are complete. One-way operations are special
operations that return the control to the calling applications immediately after the call. How this semantics is
implemented is middleware-specific but in all cases one-way operations:
• Cannot have a result (return type must be void, no out or inout parameters).
• Cannot trigger exceptions.
In a CORBA scope, operations may be added a context expression, as specified in the following additional rules:
(123) <op_with_context> ::= {<op_dcl> | <op_oneway_dcl>} <context_expr>
(124) <context_expr> ::= "context" "(" <string_literal> { "," <string_literal>* } ")"
A context expression specifies which elements of the client’s context may affect the performance of a request by the
object. The run-time system guarantees to make the value (if any) associated with each <string_literal> in the client’s
context available to the object implementation when the request is delivered. The ORB and/or object is free to use
information in this request context during request resolution and performance.
The absence of a context expression indicates that there is no request context associated with requests for
this operation.
Each <string_literal> is a non-empty string. If the character * appears in a <string_literal>, it must appear only once,
as the last character of the <string_literal>, and must be preceded by one or more characters other than *.
The mechanism by which a client associates values with the context identifiers is described in [CORBA], part 1, Sub
clause 8.6 "Context Object" .
Names defined by the CORBA specification are in a module named CORBA. In an IDL specification, however, IDL
keywords such as Object must not be preceded by a "CORBA::" prefix. Other interface names such as TypeCode are
not IDL keywords, so they must be referred to by their fully scoped names (e.g., CORBA::TypeCode) within an IDL
specification.
IDL, v4.2 63
The file orb.idl contains the IDL definitions for the CORBA module. Except for CORBA::TypeCode, the file orb.idl
must be included in IDL files that use names defined in the CORBA module. IDL files that use CORBA::TypeCode
may obtain its definition by including either the file orb.idl or the file TypeCode.idl.
The following table selects in Table 7-6 the keywords that are specific to this building block and removes the others.
context
import
local
Object oneway
typeid
typeprefix
7.4.7.1 Purpose
This building block adds the syntactical elements that are specific to value types when used in CORBA as well as
provides explanations specific to a CORBA usage of the imported elements.
Note – This building block has been designed as separated from Building Block CORBA-Specific – Interfaces, to
allow CORBA profiles without value types.
64 IDL, v4.2
7.4.7.2 Dependencies with other Building Blocks
This building-bock is based on Building Block Value Types and complements Building Block CORBA-Specific –
Interfaces. Transitively, it relies on Building Block Interfaces – Full, Building Block Interfaces – Basic and Building
Block Core Data Types.
7.4.7.3 Syntax
All these constructs are presented in the following sub clauses as far as it is needed to understand their syntax. For
more details on their precise semantics, refer to the CORBA documentation.
It is often convenient to define a value type with no inheritance or operations and with a single state member. A
shorthand IDL notation is used to simplify the use of value types for this kind of simple containment, referred to as a
value box. Such boxed value types are defined with the following syntax:
(126) <value_box_def> ::= "valuetype" <identifier> <type_spec>
IDL, v4.2 65
• An identifier (<identifier>) to name the boxed value type.
• The type specification of the unique state member of the boxed value type. (<type_spec>).
Since "boxing" a value type would add no additional properties to the value type, it is an error to box value types. Any
IDL type may be used to declare a value box except a value type.
Value boxes are particularly useful for strings and sequences. Basically they avoid creating what would actually be an
additional namespace that would contain only one name.
The above IDL provides similar functionality to writing the following one. However the type identities would be
different.
module Example {
interface Foo {
... /* anything */
};
valuetype FooSeq {
public sequence<Foo> data;
};
interface Bar {
void doIt (in FooSeq seq);
};
};
Note – The declaration of a boxed value type does not open a new scope. Thus a construction such as: valuetype
FooSeq sequence <FooSeq>; is not legal IDL. The identifier being declared as a boxed value type cannot be used
subsequent to its initial use and prior to the completion of the boxed value declaration.
In this building block, value types as well as interfaces may be abstract. They are called abstract because they cannot
be instantiated. Only concrete types derived from them may be actually instantiated and implemented.
Abstract types may be used to specify a type where a type specification is required (for example as a return type of an
operation).
As opposed to concrete value types, abstract value types are stateless (essentially they are a bundle of operation
signatures with a purely local implementation). To create an abstract value type, the following syntax applies:
66 IDL, v4.2
(127) <value_abs_def> ::= "abstract" "valuetype" <identifier> [ <value_inheritance_spec> ]
"{" <export>* "}"
Because no state information may be specified (only local operations are allowed), abstract value types are not subject
to the single inheritance restrictions placed upon concrete value types. Therefore a value type may inherit from several
abstract value types. In return an abstract value type cannot inherit from a concrete one.
Note – A concrete value type with an empty state is not an abstract value type.
An abstract interface is an entity, which may at runtime represent either a regular interface or a value type. Like an
abstract value type, it is a pure bundle of operations with no state. It is declared with specifying abstract interface as
interface kind.
(129) <interface_kind> ::+ "abstract" "interface"
Unlike an abstract value type, it does not imply pass-by-value semantics, and unlike a regular interface type, it does not
imply pass-by-reference semantics. Instead, the entity’s runtime type determines which of these semantics are used.
A value type may support several abstract interfaces (and only one concrete one).
The terminology that is used to describe value type inheritance is directly analogous to that used to describe interface
inheritance (see 7.4.3.4.3.2.1, Inheritance Rules).
The name scoping and name collision rules for value types are identical to those for interfaces.
Values may be derived from other values and can support an interface.
Once implementation (state) is specified at a particular point in the inheritance hierarchy, all derived value types
(which must of course implement the state) may only derive from a single (concrete) value type. They can however
support an additional interface.
The single immediate base concrete value type, if present, must be the first element specified in the inheritance list of
the value declaration’s IDL. The interfaces it supports are listed following the supports keyword.
While a value type may only directly support one interface, it is possible for the value type to support other interfaces
as well through inheritance. In this case, the supported interface must be derived, directly or indirectly, from each
interface that the value type supports through inheritance. For example:
interface I1 { };
interface I2 { };
interface I3: I1, I2 { };
abstract valuetype V1 supports I1 { };
abstract valuetype V2 supports I2 { };
valuetype V3: V1, V2 supports I3 { }; // Legal
valuetype V4: V1 supports I2 { }; // Illegal
IDL, v4.2 67
Boxed value types may not be derived from, nor may they derive from, anything else.
Table 7-19: Possible inheritance relationships between value types and interfaces
May Abstract Interface Abstract Concrete Boxed
inherit Interface Value Value value
from
Abstract multiple no no no no
Interface
Interface multiple multiple no no no
In a CORBA context, a value type may optionally indicate that its marshaling is custom-made by prefixing the
valuetype keyword with custom, as shown in the following rule:
(128) <value_kind> ::+ "custom" "valuetype"
By this mean, value types can override the default marshaling/unmarshaling model and provide their own way to
encode/decode their state. Custom marshaling is intended to be used to facilitate integration of existing "class libraries"
and other legacy systems. It is explicitly not intended to be a standard practice, nor used in other OMG specifications
to avoid "standard ORB" marshaling.
The fact that a value type has some custom marshaling code is declared explicitly in the IDL. This explicit declaration
has two goals:
• Type safety - stubs and skeleton can know statically that a given type is custom marshaled and can then do a
sanity-check on what is coming over the wire.
• Efficiency - for value types that are not custom marshaled no run time test is necessary in the marshaling code.
If a custom marshaled value type has a state definition, the state definition is treated the same as that of a non-custom
value type for mapping purposes (i.e., the fields show up in the same fashion in the concrete programming language). It
is provided to help with application portability.
Custom value types can never be safely truncated to base (i.e., they always require an exact match for their
RepositoryId in the receiving context).
Once a value type has been marked as custom, it needs to provide an implementation that marshals and unmarshals the
value type. The marshaling code encapsulates the application code that can marshal and unmarshal instances of the
68 IDL, v4.2
value type over a stream using the CDR encoding. It is the responsibility of the implementation to marshal the state of
all of its base types.
For more details regarding the implementation of custom marshaling, refer to [CORBA].
7.4.7.4.5 Truncatable
A stateful value that derives from another stateful value may specify that it is truncatable by prefixing the inheritance
specification with the truncatable keyword as shown on the following rule:
(130) <value_inheritance_spec>
::+ ":" ["truncatable"] <value_name> { "," <value_name> }*
[ "supports" <interface_name> { "," <interface_name> }* ]
This means that the middleware is allowed to "truncate" an instance to become an instance of any of its truncatable
parent (stateful) value types under certain conditions (see the CORBA documentation for more details). Note that all
the intervening types in the inheritance hierarchy must be truncatable in order for truncation to a particular type to be
allowed.
Because custom values require an exact type match between the sending and receiving context, truncatable may not
be specified for a custom value type.
Non-custom value types may not (transitively) inherit from custom value types. Boxed value types may not be
derived from, nor may they derive from, anything else.
In a CORBA context, all value types have a conventional base type called ValueBase. This is a type, which fulfills a
role that is similar to that played by Object for interfaces. That root may be used in an IDL specification wherever a
value type may be used.
(131) <base_type_spec> ::+ <value_base_type>
(132) <value_base_type> ::= "ValueBase"
Conceptually it supports the common operations available on all value types. See Value Base Type Operation for a
description of those operations. In each language mapping ValueBase will be mapped to an appropriate base type that
supports the marshaling/unmarshaling protocol as well as the model for custom marshaling.
The mapping for other operations, which all value types must support, such as getting meta information about the type,
may be found in the specifics for each language mapping.
The following table selects in Table 7-6 the keywords that are specific to this building block and removes the others.
IDL, v4.2 69
custom
truncatable
ValueBase
7.4.8.1 Purpose
Purpose of that building block is to gather the minimal subset of CCM that would be useful to any component model.
This building block complements Building Block Interfaces – Basic. Transitively, it relies on Building Block Core
Data Types.
7.4.8.3 Syntax
70 IDL, v4.2
(139) <component_body> ::= <component_export>*
(140) <component_export> ::= <provides_dcl> ";"
| <uses_dcl> ";"
| <attr_dcl> ";"
(141) <provides_dcl> ::= "provides" <interface_type> <identifier>
(142) <interface_type> ::= <scoped_name>
(143) <uses_dcl> ::= "uses" <interface_type> <identifier>
This building block allows declaring simple components with basic ports.
(133) <definition> ::+ <component_dcl> ";"
A <component_header> declares the primary characteristics of a component interface. Its syntax is as follows:
(137) <component_header> ::= "component" <identifier> [ <component_inheritance_spec> ]
(138) <component_inheritance_spec>
::= ":" <scoped_name>
IDL, v4.2 71
Note – A component may inherit from at most one component. The features that are inherited by the derived
component are its attributes and basic ports (facets and/or receptacles).
Note – A component forms a naming scope, nested within the scope in which the component is declared.
7.4.8.4.2.1 Facets
A component type may provide several independent interfaces to its clients in the form of facets. Facets are intended to
be the primary vehicle through which a component exposes its functional application behavior to clients during normal
execution. A component may exhibit zero or more facets.
7.4.8.4.2.2 Receptacles
A component definition can describe the ability to accept object references upon which the component may invoke
operations. When a component accepts an object reference in this manner, the relationship between the component and
the referent object is called a connection; they are said to be connected. The conceptual point of connection is called a
receptacle. A receptacle is an abstraction that is concretely manifested on a component as a set of operations for
establishing and managing connections. A component may exhibit zero or more receptacles.
72 IDL, v4.2
The syntax for describing a receptacle is as follows:
(143) <uses_dcl> ::= "uses" <interface_type> <identifier>
7.4.8.4.2.3 Attributes
In addition to basic ports, components may be given attributes, which are declared exactly as interface attributes. For
more details see the related clause (7.4.3.4.3.3.2, Attributes).
Note – Component attributes are intended to be used during a component instance’s initialization to establish its
fundamental behavioral properties. Although the component model does not constrain the visibility or use of attributes
defined on the component, it is generally assumed that they will not be of interest to the same clients that will use the
component after it is configured. Rather, it is intended for use by component factories or by deployment tools in the
process of instantiating an assembly of components.
Components may be forward-declared, which allows the definition of components that refer to each other.
As expressed in the following rule, a forward declaration consists simply of the component keyword followed by an
<identifier> that names the component. The actual definition must follow later in the specification.
(135) <component_forward_dcl>
::= "component" <identifier>
The following table selects in Table 7-6 the keywords that are specific to this building block and removes the others.
component
IDL, v4.2 73
provides
uses
7.4.9.1 Purpose
This building block adds to the former the concept of homes. Homes are special interfaces for creating and managing
instances of components.
This building block complements Building Block Components – Basic. Transitively, it relies on Building Block
Interfaces – Basic and Building Block Core Data Types.
7.4.9.3 Syntax
74 IDL, v4.2
7.4.9.4 Explanations and Semantics
A home declaration describes an interface for managing instances of a specified component type. The salient
characteristics of a home declaration are as follows:
• A home declaration must specify exactly one component type that it manages. Multiple homes may manage the
same component type.
• Home declarations may include any declarations that are legal in normal interface declarations.
• Home declarations support single inheritance from other home definitions.
A home header describes fundamental characteristics of a home interface. It is declared according to the following
syntax:
(146) <home_header> ::= "home" <identifier> [ <home_inheritance_spec> ]
"manages" <scoped_name>
(147) <home_inheritance_spec> ::= ":" <scoped_name>
In addition to plain operations and attributes, identical to the ones an interface body may comprise, a home body may
also comprise factory operations, which are specific operations dedicated to creating component instances.
IDL, v4.2 75
The syntax of a factory operation is as follows:
(150) <factory_dcl> ::= "factory" <identifier> "(" [ <factory_param_dcls> ] ")" [ <raises_expr> ]
(151) <factory_param_dcls> ::= <factory_param_dcl> {"," <factory_param_dcl>}*
(152) <factory_param_dcl> ::= "in" <type_spec> <simple_declarator>
The following table selects in Table 7-6 the keywords that are specific to this building block and removes the others.
factory
home
manages
76 IDL, v4.2
7.4.10 Building Block CCM-Specific
7.4.10.1 Purpose
This building block complements the former one in order to support the full CCM extension to CORBA.
This building block relies on Building Block Components – Basic and Building Block CORBA-Specific – Value
Types. Transitively, it relies on Building Block CORBA-Specific – Interfaces, Building Block Value Types, Building
Block Interfaces – Full, Building Block Interfaces – Basic and Building Block Core Data Types.
7.4.10.3 Syntax
IDL, v4.2 77
7.4.10.4 Explanations and Semantics
All these constructs are presented in the following sub clauses as far as it is needed to understand their syntax. For
more details on their precise semantics, refer to [CORBA], Part3.
The main addition of this building block consists in support for event interactions, namely
• The ability to define event types.
• The ability to add ports to send (publish or emit) and receive (consume) events.
Event type is a specialization of value type dedicated to asynchronous component communication. There are several
kinds of event type declarations: "regular" event types, abstract event types, and forward declarations.
78 IDL, v4.2
An event can contain all the elements that a value can as described in 7.4.5.4.1.3 Value Element (i.e., attributes,
operations, initializers, state members).
Event types may also be abstract. They are called abstract because an abstract event type may not be instantiated. No
state members or initializers may be specified. However, local operations may be specified. Essentially they are a
bundle of operation signatures with a purely local implementation.
Note – A concrete event type with an empty state is not an abstract event type.
A forward declaration declares the name of an event type without defining it. This permits the definition of event types
that refer to each other. The syntax consists simply of the eventtype keyword followed by an <identifier> that names
the event type, as expressed in the following rule:
(167) <event_forward_dcl> ::= [ "abstract" ] "eventtype" <identifier>
Multiple forward declarations of the same event type name are legal.
As event type is a specialization of value type then event type inheritance is directly analogous to value inheritance
(see 7.4.7.4.3, Value Inheritance Rules for a detailed description of the analogous properties for value types). In
addition, an event type could inherit from a single immediate base concrete event type, which must be the first element
specified in the inheritance list of the event declaration’s IDL. It may be followed by other abstract values or events
from which it inherits.
Event ports can be split into event sources and event sinks.
An event source embodies the potential for the component to generate events of a specified type, and provides
mechanisms for associating consumers with sources.
There are two categories of event sources, publishers and emitters. Both are implemented using event channels
supplied by the container. An emitter can be connected to at most one consumer. A publisher can be connected through
the channel to an arbitrary number of consumers, who are said to subscribe to the publisher event source. A component
may exhibit zero or more emitters and publishers.
IDL, v4.2 79
7.4.10.4.1.2.1.1 Publishers
7.4.10.4.1.2.1.2 Emitters
An event sink embodies the potential for the component to receive events of a specified type. An event sink is, in
essence, a special-purpose facet whose type is an event consumer. External entities, such as clients or configuration
services, can obtain the reference for the consumer interface associated with the sink.
In this profile:
80 IDL, v4.2
• A home declaration may specify a list of interfaces that the home supports.
• A home declaration may specify a primary key type. Primary keys are values assigned by the application
environment that uniquely identify component instances managed by a particular home.
• Home operations may include finder operations. Finder operations aim at retrieving components managed by
the home.
The syntax to add supported interfaces declaration within the home header is as follows:
(155) <supported_interface_spec>
::= "supports" <scoped_name> { "," <scoped_name> }*
The syntax for adding a primary key definition within the home header is as follows:
(163) <primary_key_spec> ::= "primarykey" <scoped_name>
The third extension consists in the ability for a receptacle to be connected to several facets. This is indicated by adding
the multiple keyword in the receptacle definition as shown in the following rule:
IDL, v4.2 81
(158) <uses_dcl> ::+ "uses" "multiple" <interface_type> <identifier>
The presence of this keyword indicates that the receptacle may accept multiple connections simultaneously, and results
in different operations on the component’s associated interface.
7.4.10.4.4 Alignment with CORBA-specific Features related to Interfaces and Value Types
As expressed in the following grammar elements, in this profile components may also support interfaces:
(154) <component_header> ::+ "component" <identifier> [ <component_inheritance_spec> ]
<supported_interface_spec>
(155) <supported_interface_spec>
::= "supports" <scoped_name> { "," <scoped_name> }*
As for all other CORBA interfaces, in this building block, Object may be used wherever an interface is required.
Object denotes the root for all CORBA interfaces.
(157) <interface_type> ::+ "Object"
The following table selects in Table 7-6 the keywords that are specific to this building block and removes the others.
consumes
emits
eventtype finder
multiple
primarykey
publishes
82 IDL, v4.2
7.4.11 Building Block Components – Ports and Connectors
7.4.11.1 Purpose
This building block complements the Building Block Components – Basic with the ability to define extended ports and
connectors.
This building block relies on the Building Block Components – Basic. Transitively, it relies on Building Block
Interfaces – Basic and Building Block Core Data Types.
7.4.11.3 Syntax
The following set of rules forms the syntax of this building block:
(171) <definition> ::+ <porttype_dcl> ";"
| <connector_dcl> ";"
(172) <porttype_dcl> ::= <porttype_def>
| <porttype_forward_dcl>
(173) <porttype_forward_dcl> ::= "porttype" <identifier>
(174) <porttype_def> ::= "porttype" <identifier> "{" <port_body> "}"
(175) <port_body> ::= <port_ref> <port_export>*
(176) <port_ref> ::= <provides_dcl> ";"
| <uses_dcl> ";"
| <port_dcl> ";"
(177) <port_export> ::= <port_ref>
| <attr_dcl> ";"
(178) <port_dcl> ::= {"port" | "mirrorport"} <scoped_name> <identifier>
(179) <component_export> ::+ <port_dcl> ";"
(180) <connector_dcl> ::= <connector_header> "{" <connector_export>+ "}"
(181) <connector_header> ::= "connector" <identifier> [ <connector_inherit_spec> ]
(182) <connector_inherit_spec> ::= ":" <scoped_name>
IDL, v4.2 83
(183) <connector_export> ::= <port_ref>
| <attr_dcl> ";"
As expressed in the following rule, this building block allows creating new port types (aka extended ports) and
connectors.
(171) <definition> ::+ <porttype_dcl> ";"
| <connector_dcl> ";"
An Extended Port is a grouping of basic ports (facets and/or receptacles) that are to be used jointly to support
consistently a given interaction. Those basic ports formalize the programming contract between a component with this
extended port and the connector's fragment (see below) that will realize the related interaction on behalf of the
component. As such, those basic ports are always local and correspond to interfaces to be called (receptacles) or call-
back interfaces (facets).
Before it can be used in a component, an extended port has to be defined through the declaration of its type.
A port type may be defined or forward declared as expressed in the following rule:
(172) <porttype_dcl> ::= <porttype_def>
| <porttype_forward_dcl>
A forward declaration is made of the porttype keyword followed by the name of the port type (<identifier>). Such
declarations allow attaching ports to components or connectors as well as embedding them inside other extended ports
while their port types are not fully defined yet.
(173) <porttype_forward_dcl> ::= "porttype" <identifier>
84 IDL, v4.2
• Optionally other facets receptacles or ports as well as attributes (<attr_dcl>).
Note – An extended port may thus embed another extended port. However no cycles are allowed among port type
definitions.
Once a port type has been declared, ports of that kind may be attached to components with the following syntax:
(178) <port_dcl> ::= {"port" | "mirrorport"} <scoped_name> <identifier>
(179) <component_export> ::+ <port_dcl> ";"
7.4.11.4.3 Connectors
Connectors are used to specify interaction mechanisms between components. Connectors can have ports in the same
way as components. They can be composed of simple ports (provides and uses) or extended ports (very likely in their
reverse form).
IDL, v4.2 85
A connector will concretely be composed of several parts (called fragments) that will consist of executors, each in
charge of realizing a part of the interaction. Each fragment will be co-localized to the component using it.
The following table selects in Table 7-6 the keywords that are specific to this building block and removes the others.
Table 7-24: Keywords specific to Building Block Components – Ports and Connectors
connector
mirrorport
port porttype
7.4.12.1 Purpose
The purpose of this building block is to allow embedding constructs in template modules. Template modules may be
parameterized by a variety of parameters (called formal parameters), which transitively makes all the embedded
constructs parameterized by the same parameters. Before using it, a template module needs to be instantiated with
values suited for the formal parameters. Instantiation of the template module instantiates all the embedded constructs.
86 IDL, v4.2
7.4.12.2 Dependencies with other Building Blocks
Although this building block relies only on Building Block Core Data Types, it can be seen as orthogonal to all the
other ones, meaning that all the constructs that are selected for a profile that embeds this specific building block may
be embedded in a template module and thus benefit from parameterization.
7.4.12.3 Syntax
(184) <definition> ::+ <template_module_dcl> ";"
| <template_module_inst> ";"
(185) <template_module_dcl> ::= "module" <identifier> "<" <formal_parameters> ">"
"{" <tpl_definition> +"}"
(186) <formal_parameters> ::= <formal_parameter> {"," <formal_parameter>}*
(187) <formal_parameter> ::= <formal_parameter_type> <identifier>
(188) <formal_parameter_type> ::= "typename" | "interface" | "valuetype" | "eventtype"
| "struct" | "union" | "exception" | "enum" | "sequence"
| "const" <const_type>
| <sequence_type>
(189) <tpl_definition> ::= <definition>
| <template_module_ref> ";"
(190) <template_module_inst> ::= "module" <scoped_name> "<" <actual_parameters> ">" <identifier>
(191) <actual_parameters> ::= <actual_parameter> { "," <actual_parameter>}*
(192) <actual_parameter> ::= <type_spec>
| <const_expr>
(193) <template_module_ref> ::= "alias" <scoped_name> "<" <formal_parameter_names> ">" <identifier>
(194) <formal_parameter_names>
::= <identifier> { "," <identifier>}*
This building block adds the facility to declare and instantiate template modules:
(184) <definition> ::+ <template_module_dcl> ";"
| <template_module_inst> ";"
IDL, v4.2 87
(189) <tpl_definition> ::= <definition>
| <template_module_ref> ";"
A module template instantiation consists in providing values to the template parameters and a name to the resulting
module. Once instantiated, the resulting module is exactly as a classical module.
88 IDL, v4.2
7.4.12.4.3 References to a Template Module
An alias directive allows referencing an existing template module inside a template module definition.
This directive allows providing an alias name (which can be identical to the template module name) to the existing
template module and the list of formal parameters to be used for the referenced module instantiation. Note that that list
must be a subset of the formal parameters of the embedding module and that each specified formal parameter must be
of a compliant type for the required one. For example:
module MyTemplModule <typename T, struct S, long n > {
interface Foo {...}
…}
module MySecondTemplModule <typename T1, typename T2, struct S1, struct S2, long m> {
alias MyTemplModule<T2, S2, m> MyTemplModule; // OK
alias MyTemplModule2<S1, S2, m> MyTemplModule; // OK (S1 < T)
alias MyTemplModule3<T2, T1, m> MyTemplModule2; // Error (T1 not compliant for S)
interface Bar : MyTemplModule::Foo {...}
...}
When the embedding module will be instantiated, then the referenced module will be instantiated in the scope of the
embedding one (i.e., as a sub-module).
The following table selects in Table 7-6 the keywords that are specific to this building block and removes the others.
IDL, v4.2 89
7.4.13 Building Block Extended Data-Types
7.4.13.1 Purpose
This building block adds a few data constructs that are proven to be useful for describing data models.
This building block complements the Building Block Core Data Types.
7.4.13.3 Syntax
(195) <struct_def> ::+ "struct" <identifier> ":" <scoped_name> "{" <member>* "}"
| "struct" <identifier> "{" "}"
(196) <switch_type_spec> ::+ <wide_char_type>
| <octet_type>
(197) <template_type_spec> ::+ <map_type>
(198) <constr_type_dcl> ::+ <bitset_dcl>
| <bitmask_dcl>
(199) <map_type> ::= "map" "<" <type_spec> "," <type_spec> "," <positive_int_const> ">"
| "map" "<" <type_spec> "," <type_spec> ">"
(200) <bitset_dcl> ::= "bitset" <identifier> [":" <scoped_name>] "{" <bitfield>* "}"
(201) <bitfield> ::= <bitfield_spec> <identifier>* ";"
(202) <bitfield_spec> ::= "bitfield" "<" <positive_int_const> ">"
| "bitfield" "<" <positive_int_const> "," <destination_type> ">"
(203) <destination_type> ::= <boolean_type> | <octet_type> | <integer_type>
(204) <bitmask_dcl> ::= "bitmask" <identifier> "{" <bit_value> { "," <bit_value> }* "}"
(205) <bit_value> ::= <identifier>
(206) <signed_int> ::+ <signed_tiny_int>
(207) <unsigned_int> ::+ <unsigned_tiny_int>
(208) <signed_tiny_int> ::= “int8”
(209) <unsigned_tiny_int> ::= “uint8”
(210) <signed_short_int> ::+ “int16”
(211) <signed_long_int> ::+ “int32”
90 IDL, v4.2
(212) <signed_longlong_int> ::+ “int64”
(213) <unsigned_short_int> ::+ “uint16”
(214) <unsigned_long_int> ::+ “uint32”
(215) <unsigned_longlong_int> ::+ “uint64”
The following rule complements the structure definition with the possibility to add a single inheritance specification
and to define a structure without any member:
(195) <struct_def> ::+ "struct" <identifier> ":" <scoped_name> "{" <member>* "}"
| "struct" <identifier> "{" "}"
Single inheritance is denoted by a colon (:) followed by a scoped name that must correspond to the name of a
previously defined structure.
When a structure type inherits from another structure type, it is considered as extending the latter, which is then
considered as its base type. Members of such a structure consist in all the members of its base type plus all the ones
that are declared locally.
In the Building Block Core Data Types, union discriminators could be the following (cf. rule (51))
• Either one of the following types: integer, char, boolean or an enum type.
• Or a reference (<scoped_name>) to one of these.
Within this building block the following rule adds the following types: wchar (wide char) or octet
(196) <switch_type_spec> ::+ <wide_char_type>
| <octet_type>
Accordingly, the scoped name may also reference one of these types.
As expressed in the following rules, the new types provided by this building-block include maps, bit sets, and bit
masks:
(197) <template_type_spec> ::+ <map_type>
IDL, v4.2 91
(198) <constr_type_dcl> ::+ <bitset_dcl>
| <bitmask_dcl>
7.4.13.4.3.1 Maps
Maps are collections similar to sequences but where items are registered (and thus retrieved) associated with a key. As
sequences, maps may be bounded or unbounded. As expressed in the following rule, the syntax to define map types is
the same as that for sequence types with two exceptions:
• The sequence keyword is replaced by the new map keyword.
• The single type parameter that appears in a sequence definition is replaced by two type parameters in a map
definition: the first one is the key element type; the second one is the value element type.
(199) <map_type> ::= "map" "<" <type_spec> "," <type_spec> "," <positive_int_const> ">"
| "map" "<" <type_spec> "," <type_spec> ">"
Bit sets are sequences of bits stored optimally and organized in concatenated addressable pieces called bit fields,
themselves stored optimally. "Stored optimally" means that one bit uses just one bit in memory. "Concatenated" means
that each bit field will be placed in memory just after its predecessor within the bit set (no alignment considerations
apply).
Within a bit set, bit fields are sequences of bits stored optimally, to be manipulated as a whole. Their specification is as
follows:
(202) <bitfield_spec> ::= "bitfield" "<" <positive_int_const> ">"
| "bitfield" "<" <positive_int_const> "," <destination_type> ">"
(203) <destination_type> ::= <boolean_type> | <octet_type> | <integer_type>
It comprises:
92 IDL, v4.2
• The bitfield keyword
• One or two parameters between angular brackets (< >):
• The first one (<positive_int_const>) is the number of bits that can be stored (its size). The maximum
value is 64.
• The second optional one (<destination_type>) specifies the type that will be used to manipulate the bit
field as a whole. This type can be boolean, octet or any integer type either signed or unsigned (i.e., short,
unsigned short, long, unsigned long, long long, or unsigned long long).
• When the destination type is given, the number of stored bits cannot exceed its size (i.e., 1 for
boolean, 8 for octet, 16 for short or unsigned short, 32 for long or unsigned long and 64 for long
long or unsigned long long).
• When no destination type is given, it takes as default value the smallest type able to store the bit field
with no loss (i.e., boolean if size is 1, octet if it is between 2 and 8, unsigned short if it is between 9
and 16, unsigned long if it is between 17 and 32 and unsigned long long if it is between 33 and 64).
Note – Purpose of bit sets is to minimize as much as possible their memory footprint. In the following example, the
total memory occupancy of MyBitset is 30:
bitset MyBitset {
bitfield<3> a; // a is stored in 3 bits (and will be manipulable as a char)
bitfield<1> b; // b is stored in 1 bit (and will be manipulable as a boolean)
bitfield<4>; // 4 unused bits
bitfield<10> c; // c is stored in 10 bits (and will be manipulable as an unsigned short)
bitfield<12, short> d; // d is stored in 12 bits (and will be manipulable as a short)
};
Bit masks are enumerated types (like enumerations) aiming at easing bit manipulation.
Like an enumeration, a bit mask consists in a sequence of values named by an identifier. However those values are not
like in a classical enumeration but computed based on their position within the bit mask, to form a mask that can be
used to easily set or test the bit in that position. Those values are ordered starting with the less significant bit. For
IDL, v4.2 93
example, the actual value for the first one (which corresponds to bit in position 0) will be 0x01, the value for the
second one (position 1) 0x01 << 1 and so on as in the following example:
bitmask MyBitMask {
flag0, // 0x01 << 0
flag1, // 0x01 << 1
flag2, // 0x01 << 2
flag3, // 0x01 << 3
flag4, // 0x01 << 4
flag5, // 0x01 << 5
flag6, // 0x01 << 6
flag7 // 0x01 << 7
};
Note – Thanks to @position annotations, it is possible to give values only to bits that are useful.
Note – Although it is not recommended, annotated bit values can be declared unordered. In any cases, no duplicates
are allowed.
Note – Non-annotated bit values may be declared with annotated ones. A non-annotated bit value will always be
assumed as just following the one which is before, like in the following example:
bitmask MyBitMask {
@position (0) flag0, // 0x01 << 0
flag1, // 0x01 <<1 (just after 0)
@position (4) flag4, // 0x01 << 4
@position (2) flag2, // 0x01 <<2
flag3, // 0x01 <<3 (just after 2)
flagx, // ERROR, should be 0x01 <<4 but duplicates flag4
};
The Building Block Core Data Types, defines integer types that have well defined value ranges spanning from “short”
integers that can hold 16 bits of information to “long long” integers that can hold 64 bits, see Table 7-13: Integer types.
It does not include an integer type restricted to holding 8 bits of information.
94 IDL, v4.2
Within this building block the following rules add the following types: int8 (signed 8-bit integer) and uint8 (unsigned
8-bit integer):
(206) <signed_int> ::+ <signed_tiny_int>
(207) <unsigned_int> ::+ <unsigned_tiny_int>
(208) <signed_tiny_int> ::= “int8”
(209) <unsigned_tiny_int> ::= “uint8”
The Building Block Core Data Types, defines integer types using the keywords short, long, long long, unsigned
short, unsigned long, and unsigned long long. These integer types have specified value ranges, see Table 7-13:
Integer types. However the value range is not explicit in the type name. This could lead to ambiguity especially for
people familiar with programming languages, such as C or C++, which use the same keywords and yet don’t fully
specify the value range.
Within this building block the following rules add new keywords int16, int32, int64, uint16, uint32, uint64 for the
same primitive types, which make the value ranges explicit:
(210) <signed_short_int> ::+ “int16”
(211) <signed_long_int> ::+ “int32”
(212) <signed_longlong_int> ::+ “int64”
(213) <unsigned_short_int> ::+ “uint16”
(214) <unsigned_long_int> ::+ “uint32”
(215) <unsigned_longlong_int> ::+ “uint64”
The integer types defined in the Building Block Core Data Types have their value ranges defined in see Table 7-13:
Integer types. The table below defines the ranges for the integer in the Building Block Extended Data-Types and their
relation to the Building Block Core Data Types where appropriate.
uint8 0 … 28 - 1 N/A
16
uint16 0…2 -1 unsigned short
32
uint32 0…2 -1 unsigned long
IDL, v4.2 95
7.4.13.5 Specific Keywords
The following table selects in Table 7-6 the keywords that are specific to this building block and removes the others.
map
7.4.14.1 Purpose
The only purpose of this building block is to allow the use of anonymous types, i.e., template types or arrays that were
not given a name by a typedef directive.
Anonymous types may cause a number of problems for language mappings and were therefore deprecated in a
previous version of CORBA IDL. However, they offer an increased expression power that proves to be useful in many
occasions.
The new IDL organization in building blocks allows defining profiles where anonymous types are forbidden as well as
others where they will be supported:
• Profiles that do not support use of anonymous types must not embed this building block. With such a profile, all
anonymous types must be given a name with a typedef directive before any use (see 7.4.1.4.4.7, Naming Data
TypesNaming Data Types).
96 IDL, v4.2
• Profiles that do support use of anonymous types must embed this building block.
7.4.14.3 Syntax
With the following rule, template types may be used at any place where a type specification is required:
(216) <type_spec> ::+ <template_type_spec>
Note – A template type may be used as the type parameter for another template type. For instance, the following:
sequence<sequence<long> > declares the type "unbounded sequence of unbounded sequence of long". For those
nested template declarations, white space must be used to separate the two > tokens ending the declaration so they are
not parsed as a single >> token.
7.4.15.1 Purpose
This building block defines a framework to add meta-data to IDL constructs, by means of annotations. This facility,
very similar to the one provided by Java, is a powerful means to extend the language without changing its syntax.
This building block only relies on Building Block Core Data Types. It is actually orthogonal to all others. This means
that once defined, annotations may be applied to all the IDL constructs brought by all the building blocks that are
selected to form a profile jointly with this building block.
IDL, v4.2 97
7.4.15.3 Syntax
This building block specifies how to 1) define annotations and 2) attach previously defined annotations to most IDL
constructs.
An annotation type is a form of aggregated type similar to a structure with members that could be given constant
values. An annotation is defined with a header (<annotation_header>) and a body (<annotation_body>) enclosed
within braces ({ }):
(218) <definition> ::+ <annotation_dcl> " ;"
(219) <annotation_dcl> ::= <annotation_header> "{" <annotation_body> "}"
The annotation header consists of the @annotation keyword, followed by an identifier that is the name given to the
annotation (<identifier>).
98 IDL, v4.2
An annotation body may contain:
• Annotation members (<annotation_member>)
• Declarations of enumeration types (<enum_dcl>)
• Declarations of constant values (const_dcl>)
• Typedef declarations (<typedef_dcl>)
Enumerations, constants, and typedefs declared within the annotation body may be used unscoped subsequently in the
annotation body or further when applying the annotation. They are not significant anywhere else.
Note – Annotations may be user-defined, using this syntax. They can also be implicitly defined by the IDL-processing
tools. In the latter case, the behavior should be as if the related definitions were included at the beginning of the IDL
specification.
Note – Annotations should not cause more IDL-processing errors than strictly needed. Therefore, in case of multiple
definitions of the same annotation in one IDL specification 13, the IDL-processing tools should accept them, provided
that they are consistent. In contrast, malformed definitions shall be treated as an error.
An annotation, once its type is defined, may be applied with the following syntax:
(225) <annotation_appl> ::= "@" <scoped_name> [ "(" <annotation_appl_params> ")" ]
(226) <annotation_appl_params>
::= <const_expr>
| <annotation_appl_param> { "," <annotation_appl_param> }*
12
This form is useful when the annotation carries a value whose actual type depends on the element under annotation (a default
value for instance).
13
This may happen in particular when IDL files are included.
IDL, v4.2 99
(227) <annotation_appl_param>
::= <identifier> "=" <const_expr>
Members with no default value must be given a value. Members with default value may be omitted. In that case, the
member is considered as valued with its default value.
An annotation may be applied to any IDL constructs or sub-constructs. Applying an annotation consists actually in
adding the related meta-data to the element under annotation.
Note – In case the applied annotation contains a member of type any, the value provided for that member must match
with the element under annotation.
Note – Annotations should not cause more IDL-processing errors than strictly needed. Therefore, in case an unknown
annotation is encountered, it should be ignored by the IDL-processing tools. In contrast, malformed definitions shall be
treated as an error.
This building block reuses the any keyword. There is no other new keyword, if keyword is taken as "a word, built as a
valid identifier, but with a specific meaning within the language". However, any word starting with a commercial at
(@) will now potentially denote an annotation, starting with @annotation that allows creating annotation types.
Even if the building blocks have been designed as independent as possible, they are linked by some dependencies. The
following figure represents the graph of their relationships (actually a lattice).
BB Template Modules
BB Anonymous
Types
BB Extended BB Interfaces - Basic
BB Any
Data Types
BB CORBA Specific
BB Components BB Components
Interfaces
Ports and Connectors Homes
BB CORBA Specific
Valuetypes
BB CCM Specific
A qualified name (one of the form <scoped_name>::<identifier>) is resolved by first resolving the qualifier <scoped-
_name> to a scope S, and then locating the definition of <identifier> within S. The identifier must be directly defined
in S or (if S is an interface) inherited into S. The <identifier> is not searched for in enclosing scopes.
When a qualified name begins with "::", the resolution process starts with the file scope and locates subsequent
identifiers in the qualified name by the rule described in the previous paragraph.
Inheritance causes all identifiers defined in base interfaces, both direct and indirect, to be visible in derived interfaces.
Such identifiers are considered to be semantically the same as the original definition. Multiple paths to the same
original identifier (as results from the diamond shape in Figure 7-1: Examples of Legal Multiple Inheritance on page
48) do not conflict with each other.
Inheritance introduces multiple global IDL names for the inherited identifiers. Consider the following example:
interface A {
exception E {
long L;
};
void f () raises(E);
};
interface B: A {
void g () raises(E);
};
In this example, the exception is known by the global names ::A::E and ::B::E.
Ambiguity can arise in specifications due to the nested naming scopes. For example:
interface A {
typedef string<128> string_t;
};
interface B {
typedef string<256> string_t;
};
interface C: A, B {
attribute string_t Title; // Error: Ambiguous
attribute A::string_t Name; // OK
attribute B::string_t City; // OK
};
Contents of an entire IDL file, together with the contents of any files referenced by #include statements, forms a
naming scope. Definitions that do not appear inside a scope are part of the global scope. There is only a single global
scope, irrespective of the number of source files that form a specification.
The following kinds of definitions form scopes: modules, structures, unions, maps14, interfaces 14, value types14,
operations14, exceptions14, event types14, components14, homes14. Scope applies as follows:
• The scope for a module, structure, map, interface, value type, event type, exception or home begins
immediately following its opening { and ends immediately preceding its closing }.
• The scope of an operation begins immediately following its opening ( and ends immediately preceding its
closing ).
• The scope of a union begins immediately following the (following the switch keyword, and ends immediately
preceding its closing }.
The appearance of the declaration of any of these kinds in any scope, subject to semantic validity of such declaration,
opens a nested scope associated with that declaration.
An identifier can only be defined once in a scope. However, identifiers can be redefined in nested scopes.
An identifier declaring a module is considered to be defined by its first occurrence in a scope. Subsequent occurrences
of a module declaration with the same identifier within the same scope reopens the module and hence its scope,
allowing additional definitions to be added to it.
The name of a module, structure, union, map, interface, value type, event type, exception or home may not be
redefined within the immediate scope of the module, structure, union, map, interface, value type, event type, exception
or home. For example:
module M {
typedef short M; // Error: M is the name of the module…
// …in the scope of which the typedef is.
interface I {
void i (in short j); // Error: i clashes with the interface name I
};
};
An identifier from a surrounding scope is introduced into a scope if it is used in that scope. An identifier is not
introduced into a scope by merely being visible in that scope. The use of a scoped name introduces the identifier of the
outermost scope of the scoped name.
14
Assuming that these constructs are part of the current profile.
The declaration of Inner2::inner1 is OK because the identifier Inner1, while visible in module Inner2, has not been
introduced into module Inner2 by actual use of it. On the other hand, if module Inner2 were:
module Inner2 {
typedef Inner1::S1 S2; // Inner1 introduced
typedef string inner1; // Error
typedef string S1; // OK
};
The definition of inner1 is now an error because the identifier Inner1 referring to the module Inner1 has been
introduced in the scope of module Inner2 in the first line of the module declaration. Also, the declaration of S1 in the
last line is OK since the identifier S1 was not introduced into the scope by the use of Inner1 ::S1 in the first line.
Only the first identifier in a qualified name is introduced into the current scope. This is illustrated by Inner1::S1 in the
example above, which introduces Inner1 into the scope of Inner2 but does not introduce S1. A qualified name of the
form ::X::Y::Z does not cause X to be introduced, but a qualified name of the form X::Y::Z does.
Enumeration value names are introduced into the enclosing scope and then are treated like any other declaration in that
scope. For example:
interface A {
enum E { E1, E2, E3 }; // line 1
enum BadE { E3, E4, E5 }; // Error: E3 is already introduced…
// …into the A scope in line 1 above
};
interface C {
enum AnotherE { E1, E2, E3 };
};
interface D : C, A {
union U switch (E) {
case A::E1 : boolean b; // OK.
case E2 : long l; // Error: E2 is ambiguous (notwithstanding…
// … the switch type specification)
};
};
Type names defined in a scope are available for immediate use within that scope. In particular, see 7.4.1.4.4.4.4,
Constructed Recursive Types and Forward Declarations on cycles in type definitions.
A name can be used in an unqualified form within a particular scope; it will be resolved by successively searching
farther out in enclosing scopes, while taking into consideration inheritance relationships among interfaces.
The following scopes are searched for the declaration of ArgType used on line l5:
1. Scope of N::Y before the use of ArgType.
2. Scope of N::Y’s base interface M:: B. (inherited scope).
3. Scope of module N before the definition of N::Y.
4. Global scope before the definition of N.
M::B::ArgType is found in step 2 in line l3, and that is the definition that is used in line l5, hence ArgType in line l5 is
string. It should be noted that ArgType is not char in line l5. Now if line l3 were removed from the definition of
interface M::B, then ArgType on line l5 would be char from line l4, which is found in step 3.
Following analogous search steps for the types used in the operation M:: B::opb on line l2, the type of AType used on
line l2 is long from the typedef in line l1 and the return type ArgType is string from line l3.
Once a type has been defined anywhere within the scope of a module, interface or value type, it may not be redefined
except within the scope of a nested module, interface or value type, or within the scope of a derived interface or value
type. For example:
typedef short TempType; // Scope of TempType begins here
module M {
typedef string ArgType; // Scope of ArgType begins here
struct S {
::M::ArgType a1; // Nothing introduced here
M::ArgType a2; // M introduced here
::TempType temp; // Nothing introduced here
}; // Scope of (introduced) M ends here
// ...
}; // Scope of ArgType ends here
// Scope of global TempType ends here (at end of file)
The scope of an introduced type name is from the point of introduction to the end of its enclosing scope.
A type may not be redefined within its scope or potential scope, as shown in the preceding example. This rule prevents
type names from changing their meaning throughout a non-module scope definition, and ensures that reordering of
definitions in the presence of introduced types does not affect the semantics of a specification.
Note – In the following, the definition of M::A:: U::I is legal because it is outside the potential scope of the I
introduced in the definition of M::A::S::T::ArgType. However, the definition of M::A::I is still illegal because it is
within the potential scope of the I introduced in the definition of M::A::S::T::ArgType.
module M {
typedef long ArgType;
const long I = 10;
interface A {
struct S {
struct T {
ArgType x[I]; // ArgType and I introduced
} m;
};
struct U {
long I; // OK, I is not a type name
};
enum I { I1, I2 }; // Error: I redefined
}; // Potential scope of ArgType and I ends here
};
8.1 Overview
The syntax to define annotations is given in the clause 7.4.15, Building Block Annotations. Any profile that embeds
that building block will support annotations.
In addition, this clause defines some annotations and groups them in Groups of Annotations. Groups of annotations
may be part of a given profile to complement the selected building blocks.
Any profile that includes such a group of annotations must include the Building Block Annotations.
8.2 Introduction
The annotations that are standardized here have been selected for their general purpose nature, meaning that their
application can be considered in various contexts.
Proposed groups of annotations gather annotations per concern, in order to ease their selection.
The fact that a standardized annotation is proposed in its largest possible scope doesn't mean that any specification
deciding to make use of such an annotation (and thus selecting it in its compliance profile) is forced to support its
whole possible set of applications. In return it must specify the actual usage of the annotation in its specific context.
This actual usage must remain compliant with the standardized description provided here but may be more restrictive.
More precisely the using specification:
• Shall respect totally the standardized annotation syntax.
• May clarify the actual meaning of the annotation in the specific targeted context. That actual meaning may be
more precise than, but shall remain compliant with, the general one expressed here.
The following standardized annotations are of general purpose. They may be applied on almost all kinds of elements.
This annotation allows assigning a 32-bit integer identifier to an element, with the underlying assumption that an
identifier should be unique inside its scope of application. The precise scope of uniqueness depends on the type of
element on which the annotation is applied and the purpose of such an identification. It has to be given by the
specification making use of it.
@annotation id {
unsigned long value;
};
This annotation is applicable to any elements that are parts of a set, such as data members within a constructed type or
operations within an interface.
This annotation complements the former and is applicable to any set containing elements to which allocating a 32-bit
integer identifier makes sense. It instructs to automatically allocate identifiers to the elements.
@annotation autoid {
enum AutoidKind {
SEQUENTIAL,
HASH
};
AutoidKind value default HASH;
};
The parameter allows choosing the way the identifiers are created. It could be as follows:
• SEQUENTIAL indicates that the next identifier should be computed by incrementing the previous one.
• HASH indicates that the identifiers should be computed with a hashing algorithm that gives values regardless
the order on which the elements are declared. This is the default value.
Note – The default value (TRUE) is significant when the annotation is present (this means that using the compact form
@optional will set the element as optional, which is what is expected intuitively). It does not mean that by default (i.e.,
when no annotation is present) an element is optional.
This annotation may be used to set optionality on any element that makes sense to be optional.
Note – The general idea with a position is that it defines an order (position 2 being between position 1 and position 3).
However, what actually means "position" is to be precised when using this annotation.
This annotation is applicable to any elements that are parts of a set, such as data members within a constructed type or
operations within an interface.
This annotation allows setting a constant value to any element that may be given a constant value. As opposed to @id,
@value is more versatile as it may carry any constant value. In return it does not carry any concept of uniqueness
among a set.
@annotation value {
any value;
};
When applied, the provided value must be compliant with the type of the annotated element.
This annotation may be used to set a constant value each time it is relevant. One classical example is to set specific
values to members of enumerations.
This annotation applies to any element that is constructed such as a data type or an interface. It allows specifying how
the element is allowed to evolve.
This group of annotations gathers annotations that are especially useful to define a data model. They can thus either
concern data types (i.e., constructed types) or elements of those (i.e., members of constructed types).
This annotation allows indicating that a data member is part of the key for the objects whose type is the constructed
data type owning this element. The key allows identifying an object among the set of objects of a given type. All data
items sharing the same key value are assumed to represent the same object.
@annotation key {
boolean value default TRUE;
};
112 IDL, v4.2
Note – The default value (TRUE) is significant when the annotation is present (this means that using the compact form
@key will set the element as part of the key definition, which is what is expected intuitively). It does not mean that by
default (i.e., when no annotation is present) an element is part of the key.
The annotation allows indicating that the data member must be understood by any application making use of that piece
of data. This does not mean that the data member cannot be optional. It just means that if the member is present, then it
cannot be unknown to the recipient.
@annotation must_understand {
boolean value default TRUE;
};
Note – The default value (TRUE) is significant when the annotation is present (this means that using the compact form
@must_understand will set the element as needed to be understood, which is what is expected intuitively). It does not
mean that by default (i.e., when no annotation is present) an element is of that kind.
The annotation allows selecting one member as the default within a collection. It may be applied to one of the
enumerators within an enumeration declaration to indicate the default value for the enumeration.
@annotation default_literal {
};
This group of annotations gathers means to qualify any element that can be given a constant value. Those annotations
can be applied directly to data elements such as members of constructed types or parameters of interfaces.
They can also be applied to a new type created based on a constant type (using a typedef declaration). This means that
all restrictions brought by the annotations placed on the created type will apply to all future members declared with that
new type, as shown in the following example.
@range (min=10, max=20)
typedef long MyLong;
…
struct Foo {
@range (min=10, max=20)
long bar1; // direct application
This annotation allows specifying a default value for the annotated element.
The provided value must be compliant with the type of the annotated element.
This annotation allows specifying a range of allowed values for the annotated element.
@annotation range {
any min;
any max;
};
The provided values (min and max) must be compliant with the type of the annotated element. The max value must be
greater or equal to the min value.
This annotation allows specifying a minimum value for the annotated element.
@annotation min {
any value;
};
The provided value must be compliant with the type of the annotated element.
This annotation allows specifying a maximum value for the annotated element.
@annotation max {
any value;
};
The provided value must be compliant with the type of the annotated element.
This annotation allows specifying a unit of measurement for the annotated element.
@annotation unit {
string value;
};
Note – This standard does not define specific values for given units. However, it is recommended to use standardized
abbreviations defined by BIPM 15, whenever applicable.
15
Bureau International des Poids et Mesures. Cf. http://www.bipm.org/en/measurement-units/
This annotation allows setting a size (expressed in bits) to an element or a group of elements.
@annotation bit_bound {
unsigned short value;
};
Note – Typically it may be used to force a size, smaller than the default one to members of an enumeration or to
integer elements.
Usually when a data object is mapped in memory, it is implemented as a whole, meaning that, when feasible, its data
members are placed next to each other in a single data space. This annotation forces the annotated element to be put
elsewhere, in a dedicated place. This is useful for instance to save resources when the element may be huge and is not
always present or to allow sharing of the element between data objects.
@annotation external {
boolean value default TRUE;
};
Note – The default value (TRUE) is significant when the annotation is present (this means that using the compact form
@external will set the element as external, which is what is expected intuitively). It does not mean that by default (i.e.,
when no annotation is present) an element is external.
This annotation applies to constructed types only. It allows indicating that the objects from the type under annotation
will always be nested within another one (i.e., as members of their owning object) and thus never used as top-level
objects.
@annotation nested {
boolean value default TRUE;
};
Note – The default value (TRUE) is significant when the annotation is present (this means that using the compact form
@nested will set the element as nested, which is what is expected intuitively). It does not mean that by default (i.e.,
when no annotation is present) an element is nested.
This annotation allows injecting some user-provided information into what the compiler will generate.
@annotation verbatim {
enumeration PlacementKind {
BEGIN_FILE,
BEFORE_DECLARATION,
BEGIN_DECLARATION,
END_DECLARATION,
AFTER_DECLARATION,
END_FILE
};
string language default "*";
PlacementKind placement default BEFORE_DECLARATION;
string text;
};
In addition to the text to be injected (text), this annotation has two parameters:
• The language parameter allows indicating to which language this injection applies. The defined values are as
follows:
• "c" indicates the C language.
• "c++" indicates the C++ language.
• "java" indicates the Java language.
• "idl" indicates OMG IDL.
• "*" (an asterisk) indicates any language. This is the default value.
Note – Other values may be used when relevant.
• The placement parameter allows indicating where in the generated code, this injection is to be made. The
defined values are as follows:
• BEGIN_FILE: The text string shall be copied at the beginning of the file containing the declaration of the
annotated element, before any type declarations. For example, a system implementer may use such an
annotation to inject import statements into the output.
• BEFORE_DECLARATION: The text string shall be copied immediately before the declaration of the
annotated element. For example, a system implementer may use such an annotation to inject documentation
comments into the output. This is the default value.
• BEGIN_DECLARATION: The text string shall be copied into the body of the declaration of the annotated
element before any members or constants. For example, a system implementer may use such an annotation
to inject additional declarations or implementations into the output.
• END_DECLARATION: The text string shall be copied into the body of the declaration of the annotated
element after all members or constants.
• AFTER_DECLARATION: The text string shall be copied immediately after the declaration of the annotated
element.
• END_FILE: The text string shall be copied at the end of the file containing the declaration of the annotated
element after all type declarations.
116 IDL, v4.2
8.3.6 Group of Annotations Interfaces
This annotation allows indicating that an interface is to be treated as a service. An optional parameter allows indicating
by which platform that service invocation is to be supported.
@annotation service {
string platform default "*";
};
This annotation allows indicating that an operation is one way only, meaning that related information flow will go from
the client to the server providing the related service, but not back from the server to the client.
@annotation oneway {
boolean value default TRUE;
};
This annotation may only concern operations without any return value (void return type) and without any out or inout
parameters.
Note – The default value (TRUE) is significant when the annotation is used (this means that using the compact form
@oneway will set the operation as one-way, which is what is expected intuitively). It does not mean that by default
(i.e., when no annotation is used) the operation is one-way.
This annotation allows indicating that an interface or an operation is to be made callable asynchronously.
@annotation ami {
boolean value default TRUE;
};
Note – The default value (TRUE) is significant when the annotation is used (this means that using the compact form
@ami will set the element as asynchronously callable, which is what is expected intuitively). It does not mean that by
default (i.e., when no annotation is used) it is the case.
9.1 Overview
This clause defines some relevant combinations of building blocks, called profiles. Profiles are just sets of building
blocks, possibly complemented with groups of annotations. The given profiles correspond to current usages of IDL.
They are split in two categories, the ones that are related to CORBA (including CCM) and the ones that are related to
DDS.
These profiles are not normative for the related middleware solutions (the reference for their compliance to IDL is to
be found in their respective specifications). However they are given here for illustration and a check of the relevant
breakdown in building blocks.
This profile corresponds to the plain CORBA usage, without Components (i.e., the latest IDL 2 version)
It is made of:
• Building Block Core Data Types
• Building Block Any
• Building Block Interfaces – Basic
• Building Block Interfaces – Full
• Building Block Value Types
• Building Block CORBA-Specific – Interfaces
• Building Block CORBA-Specific – Value Types
This version corresponds to CORBA minimum profile. As opposed to Plain CORBA Profile, it does not embed Any
nor Valuetypes.
It is made of:
• Building Block Core Data Types
This profile corresponds to CCM (or Lw-CCM) mandatory usage (i.e., the latest IDL3 version without optional
Generic Interaction Support).
It is made of:
• Building Block Core Data Types
• Building Block Any
• Building Block Interfaces – Basic
• Building Block Interfaces – Full
• Building Block Value Types
• Building Block CORBA-Specific – Interfaces
• Building Block CORBA-Specific – Value Types
• Building Block Components – Basic
• Building Block CCM-Specific
This profile adds to CCM Profile, the Generic Interaction Support; which is an optional CCM compliance point (also
known as IDL3+).
It is made of:
• Building Block Core Data Types
• Building Block Any
• Building Block Interfaces – Basic
• Building Block Interfaces – Full
• Building Block Value Types
• Building Block CORBA-Specific – Interfaces
• Building Block CORBA-Specific – Value Types
• Building Block Components – Basic
• Building Block CCM-Specific
• Building Block Components – Ports and Connectors
• Building Block Template Modules
It is made of:
• Building Block Core Data Types
• Building Block Anonymous Types
This profile extends Plain DDS Profile with the features provided by Extensible and Dynamic Topic Types for DDS.
It is made of:
• Building Block Core Data Types
• Building Block Extended Data-Types
• Building Block Anonymous Types
• Building Block Annotations
• Group of Annotations General Purpose
• Group of Annotations Data Modeling
• Group of Annotations Data Implementation
• Group of Annotations Code Generation
This profile allows describing interfaces that may be considered as services by RPC over DDS.
It is made of:
• Building Block Core Data Types
• Building Block Extended Data-Types
• Building Block Anonymous Types
• Building Block Interfaces – Basic
• Building Block Annotations
• Group of Annotations General Purpose
• Group of Annotations Interfaces
IDL, v4.2 121
122 IDL, v4.2
Annex A: Consolidated IDL Grammar
This annex gathers all the rules from all the building blocks.