home *** CD-ROM | disk | FTP | other *** search
-
-
-
-
-
-
- **** EARLY DRAFT ****
-
-
- A Portable Implementation of Parameterized
- Templates Using A Sophisticated C++ Macro Facility
-
-
- **** EARLY DRAFT ****
-
-
-
- Mary Fontana
- LaMott Oren
-
- Texas Instruments Incorporated
- Computer Science Center
- Dallas, TX
-
-
- Martin Neath
-
- Texas Instruments Incorporated
- Information Technology Group
- Austin, TX
-
-
- ABSTRACT
-
- The Texas Instruments C++ Object-Oriented Library
- (COOL) is a collection of classes, templates and macros
- for use by C++ programmers writing complex applica-
- tions. Parameterized types, symbolic computing and
- exception handling are significant features of COOL
- which improve the development capabilities available to
- the programmer. These features are implemented in COOL
- with a sophisticated C++ macro facility. This paper
- describes the COOL macro facility, discusses how sup-
- port for parameterized templates is built upon it, and
- provides details of two programmer interfaces (both
- implemented) for easy use of parameterized templates in
- application programs.
-
-
-
- 1. Introduction
- The Texas Instruments C++ Object-Oriented Library (COOL) is a
- collection of classes, templates and macros for use by C++ pro-
- grammers writing complex applications. It is designed to raise
- the level of abstraction for the programmer in order to facili-
- tate concentration on the problem domain, not on implementing
- base data structures, macros, and classes. In addition, COOL
-
- -1-
- provides a system-independent software platform on top of which
- applications are built. Parameterized templates, symbolic comput-
- ing, and exception handling are significant features of COOL
- which substantially improve the development capabilities avail-
- able to the C++ programmer. We wished to provide these facili-
- ties in a compiler- and machine-independent manner across several
- hardware platforms. We examined the macro definition and expan-
- sion mechanism found in standard C-preprocessors and determined
- that it is not sufficient for implementing these features. As a
- result, we developed the COOL macro facility to allow the pro-
- grammer to define powerful extensions to the C++ language in a
- seamless and unobtrusive manner. This macro facility is imple-
- mented as an extension to a standard C preprocessor [1]. The
- modifications made to the preprocessor are both portable and com-
- piler independent. This paper describes this enhanced macro
- facility, discusses how parameterized templates is built upon it,
- and provides details of two programmer interfaces (both imple-
- mented) for easy use of parameterized templates. For an overview
- of COOL see the paper, COOL - A C++ Object-Oriented Library [2].
- For complete details, see the reference document, COOL User's
- Manual [3].
-
- 2. The COOL Preprocessor and the defmacro Keyword
- Many C++ language implementations separate the preprocessor and
- compiler functions into two separate programs. Others, (such as
- the Glockenspiel C++ language system), combine the preprocessor
- and compiler into one step. Since we needed a portable utility to
- massage C++ source code that works under both scenarios and exe-
- cutes after include files and standard preprocessor directives
- have been expanded, but before the C++ compiler itself begins
- parsing, we decided to modify a C-preprocessor to support the
- COOL C++ language extensions. Thus, the COOL preprocessor is
- derived from and based upon a public domain C-preprocessor (the
- DECUS C preprocessor) made available by the DEC User's group and
- supplied on the X11R3 source tape from MIT. It has been modified
- to comply with the draft ANSI C specification with the exception
- that trigraph sequences are not supported.
-
- The draft-proposed ANSI C standard indicates that extensions and
- changes to the language or features implemented in a preprocessor
- or compiler should be made by using the #pragma keyword. The
- COOL preprocessor recognizes a #pragma defmacro declaration and
- is the single hook through which features such as the class
- macro, parameterized templates, and polymorphic enhancements have
- been implemented. The defmacro keyword provides a way to define
- and execute arbitrary filter programs or macro expanders on C++
- code fragments. The syntax of the defmacro declaration is:
-
- #pragma defmacro name "program" options
- #pragma defmacro name <program> options
-
- where name is the name of the macro, program is either the name
- of an executable file or the name of an internal preprocessor
- function which implements the macro expansion, and options are
- any combination of the following optional parameters:
-
-
-
- -2-
-
- recursive - the macro may be recursively expanded.
- expanding - the input to the macro is expanded.
- delimiter= x - the default delimiter (semi-colon) is
- replaced with x.
-
- Unknown options are passed as arguments to the macro expander
- named program. This provides the necessary handle through which
- COOL functions and language extensions can be identified. For
- example, the MACRO and template keywords are defined in a top-
- level header file with:
-
- #pragma defmacro MACRO "macro" delimiter=} recursive
- #pragma defmacro template "template" delimiter=}
-
- The implementation of the macro expander program may be either
- external or internal to the preprocessor. Fundamental COOL
- macro-expanders are implemented internal to the COOL preprocessor
- for the sole reason of providing a more efficient execution pro-
- file to reduce compile time for the application programmer. When
- the preprocessor encounters a defmacro declaration in the source
- code, it searches first for an executable file named program on
- the same search path as that used for include files. If a match
- is not found, it then searches for program in an internal prepro-
- cessor function table. If a match is still not found, an error
- is reported indicating that the macro expander could not be
- found. This search order allows an internal preprocessor defini-
- tion to be overridden by an external one.
-
- When a defmacro name is successfully recognized, the name and all
- following characters upto and including the delimiter character
- (including all matching and nested levels of {} [] () <> "" ''
- and comments found along the way) are piped into the standard
- input of the macro expander program. The expander program per-
- forms whatever function(s) is appropriate and the resulting mas-
- saged character stream is piped back onto the standard output of
- the macro expander. This output stream is scanned as new input
- by the preprocessor for any further processing that might be
- necessary. The original text in the source file is replaced with
- the preprocessor output before being sent onto the C++ compiler.
- The expansion replacing a defmacro name in the source code is C++
- 2.0 syntax acceptable to any conforming C++ translator or com-
- piler [4].
-
- 3. The MACRO Keyword
- The COOL MACRO keyword provides a powerful and flexible macro
- capability used to implement and simplify many of the features
- and functions contained in the library. A defmacro named MACRO
- (all uppercase) provides an enhanced #define macro that supports
- multi-line, arbitrary length, nested macros and cpp-directives
- with positional, optional, optional keyword, required keyword,
- rest, and body arguments. MACRO has the following syntax:
-
- MACRO name ( parmlist ) { body }
- parmlist :=
- [KEY: | REST: | BODY:] identifier [= identifier] [, parmlist]
-
-
- -3-
- where name is the name of the macro, parmlist is a list of param-
- eters separated by commas, and body is the code which replaces
- the MACRO reference. The parmlist specification allows posi-
- tional, keyword, rest, and body parameters to be identified by
- the programmer. The positional and keyword parameters may be
- required or optional. Optional parameters are supported by use of
- an equal sign followed by an identifier that specifies the
- default value. All the optional positional parameters must fol-
- low all of the required positional ones.
-
- When KEY: is specified in the parmlist, all parameters which fol-
- low are keyword parameters. Keyword parameters are position-
- independent parameters. A keyword parameter is provided a value
- in an argument list by supplying the keyword name followed by an
- equal sign and the argument value. REST: in the parmlist indi-
- cates that the remaining parameters are referenced by one named
- identifier. An optional equal sign followed by an identifier
- sets the identifier after the equal sign to the number of argu-
- ments remaining. Finally, BODY: in the parmlist indicates that
- the parameter which follows is expanded to include all the source
- code within the braces after the MACRO call. This is useful for
- passing a source code fragment onto other nested MACROs. Examples
- of these three types of arguments are given below.
-
- 3.1. MACRO Examples
- The following examples show some of the power and flexibility of
- MACRO. This first example uses both positional parameters and
- keyword parameters.
-
- MACRO set_val (size, value=NULL, KEY: low=0, high) {
- init (size, value, low, (high-low))
- }
-
- set_val has three parameters: size is a required positional
- parameter, value is an optional positional parameter that if not
- specified in a particular call has a default value of NULL, low
- is an optional keyword parameter with a default value of 0, and
- high is a required keyword parameter. In this example, the
- expansion calls the function init with four arguments. The fol-
- lowing shows several expansions of set_val.
-
- set_val (0, high=20) ----> init (0, NULL, 0, (20-0));
- set_val (0, low=5, high=15) ----> init (0, NULL, 5, (15-5));
- set_val (1, 2, high=25) ----> init (1, 2, 0, (25-0));
-
- The next example uses the REST: parameter. Note that there are
- two MACROs defined: build_table calls build_table_internal to do
- most of the work.
-
-
-
-
-
-
-
-
-
-
- -4-
-
- MACRO build_table (name, REST: rest) {
- char* name[] = { build_table_internal(rest) NULL}
- }
-
- MACRO build_table_internal (first, REST: rest=count) {
- #first,
- #if count
- build_table_internal (rest)
- #endif
- }
-
- build_table has two parameters: name is the name of the table of
- char*'s and rest refers to all the remaining arguments.
- build_table calls build_table_internal passing its rest argument.
- Note that this call is embedded within the initialization braces
- of the table and is followed by a NULL. In build_table_internal,
- first is set to the first argument of the rest argument list in
- the invoking macro call, and the remaining count arguments are
- left in rest. build_table_internal uses the ANSI # character on
- first to double quote the value. A conditional clause tests count
- to see if there are remaining arguments. If count is non-zero,
- the macro is called recursively with the remaining arguments.
- When there are no more arguments, build_table regains control and
- appends the NULL character and closing brace to the result of
- build_table_internal.
-
- A sample use of build_table is shown below to illustrate the con-
- struction of a NULL-terminated table containing character
- strings. The first line shows the macro call and the second
- shows the resulting expansion.
-
- build_table (table, 1,2,3,4,5,6,7);
-
- expands to:
-
- char* table[] = {"1", "2", "3", "4", "5", "6", "7", NULL};
-
- This last example uses the BODY: parameter and also takes advan-
- tage of the current position feature found in the COOL container
- classes [2]. This is used to implement a general purpose loop
- macro similar to that found in Common LISP [5].
-
- MACRO LOOP (type, identifier, object, BODY: body) {
- { type identifier;
- for ( object.reset(); object.next(); ) {
- identifier = object.value();
- body
- }
- }
- }
-
- LOOP has four parameters: type is the type of each element in a
- container class (such as, int), identifier is the name of a
- variable to be declared of the given type, object is the name of
- a container class instance, and body is the body of code to apply
- on each element in the container object. A specific example for
-
- -5-
- the parameterized List<int> class is shown below.
-
- extern List<int> list1;
- LOOP (int, var1, list1) { cout << var1; }
-
- expands to:
-
- extern List<int> list1;
- { int var1;
- for ( list1.reset(); list1.next(); ) {
- var1 = list1.value();
- cout << var1;
- }
- }
-
- In this example, list1 is an instance of List<int> which is a
- container class representing a list of integers. LOOP takes this
- list object and iterates through the elements, assigning each to
- a temporary integer variable var1 and printing its value. The
- net result will print all elements in the list.
-
- 4. COOL Parameterized Templates
- One of the main uses of the COOL macro facility is the implemen-
- tation of template, DECLARE and IMPLEMENT for supporting
- parameterized templates. The syntax of the template grammar is
- that as specified by Stroustrup in his paper, Parameterized Types
- for C++ [6]. COOL fully implements this functionality such that
- there will be minimal source code conversion necessary when this
- feature is finally implemented in the C++ language. COOL pro-
- vides templates for a number of parameterized classes (such as,
- Range and Iterator) and container classes (such as, Vector,
- List, Binary_Tree and Hash_Table) which are described in COOL
- User's Guide [3].
-
- 4.1. The template Keyword
- The template keyword provides a mechanism for defining parameter-
- ized classes. A parameterized class is a type-independent class.
- A typical use is a container class where the type of the con-
- tained object is specified at compile-time. For example, vectors
- can be declared to hold a specific type of element, such as, a
- vector of integers or a vector of doubles, from a single
- parameterized class, Vector<type>.
-
- A template is divided into the declarative part and the implemen-
- tation part of a class. The declarative part may occur many
- times in an application and is analogous to including a header
- file for a class which contains the class definition and its
- inline member functions. The implementation part is analogous to
- the file that contains the source code implementing the member
- and friend functions of the class. COOL provides four variations
- of template for these two parts.
-
-
- template <class type [, parms]> class name<type> { class_description };
- Defines the class template for the declarative part
- of the name class.
-
-
- -6-
- template <class type [, parms]> inline result
- name<type>::function { ... };
- Defines an inline member function for the declara-
- tive part of the name class.
-
- template <class type [, parms]> result
- name<type>::function { ... };
- Defines a member function for the implementation
- part of the name class.
-
- template <class type [, parms]> name { anything };
- Defines anything else associated with a template for
- the name class.
-
- This form is used to define such things as typedefs or friend
- functions of a parameterized class. When this form is found
- before the class template, the contents are expanded before the
- class definition. When this form is found after the class tem-
- plate, the contents are expanded as part of the class implementa-
- tion. Note that this form is not part of the parameterized type
- syntax described by Stroustrup [6]. Rather, it is something we
- found lacking in the original proposal and found very useful in
- several COOL container classes for defining predicate types for
- the class. Another use of this form is to provide automatic
- declarations of nested parameterized classes, that is, to declare
- a parameterized class for a class template which is itself
- derived from another parameterized class template.
-
- Each variation of template allows additional optional parameters
- with the following syntax:
-
- parms ::= type name [= value] [, parms]
-
- where type is the type of the parameter, (such as, class or int);
- name is the name of the parameter that is substituted when tem-
- plate is expanded; and value is the default value of parameter
- name.
-
- The following is an example of template for the class,
- Vector<type>.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -7-
-
- template <class Type> Vector { // predicate functions
- typedef int (*Vector_Type##_Predicate) (const Type&, const Type&);
- typedef Boolean (*Vector_Type##_Compare) (const Type&, const Type&);
- };
-
-
- template <class Type> class Vector<Type> { // Parameterized Vector class
- private:
- Type* v; // Vector of pointer to Type
- int num_elements; // Element count
- int size; // Size of vector object
- public:
- Vector<Type> (); // Empty constructor
- Vector<Type> (int); // Constructor with size
- Vector<Type> (const Vector<Type>&); // Constructor with reference
- ~Vector<Type> (); // Destructor
- inline Type& operator[](int n); // Operator[] overload for Type
-
- ... // ... other member functions
- };
-
-
- template <class Type> // Overload operator []
- inline Type& Vector<Type>::operator[] (int n) {
- return this->v[n];
- }
-
-
- template <class Type> // Constructor with size
- Vector<Type>::Vector<Type> (int n) {
- this->v = new Type[n];
- this->size = n;
- this->num_elements = 0;
- }
-
- ... // ... other member functions
-
-
- 4.2. An Initial Programmer Interface: DECLARE and IMPLEMENT
- As stated earlier, a template for a parameterized class is
- divided into a declarative part and an implementation part. In
- our first attempt at implementing parameterized template support,
- the programmer creates instances of a parameterized class using
- DECLARE to expand the declarative part and IMPLEMENT to expand
- the implementation part. DECLARE defines the parameterized class
- for a specific type and IMPLEMENT generates the member functions
- supporting this type-specific class. DECLARE must be used in
- every file that includes or makes use of the parameterized class.
- IMPLEMENT must be used only once in the application for each type
- over which the class is parameterized; otherwise the linker will
- generate errors about multiple versions of the same member func-
- tions. For example, to create a vector of doubles, the following
- would be used:
-
-
-
-
- -8-
-
- #include <Vector.h>
- DECLARE Vector<double>;
- IMPLEMENT Vector<double>;
- Vector<double> vs(30);
-
- DECLARE expands to code which defines a vector class of doubles
- and its associated inline member functions. IMPLEMENT causes a
- class definition with its associated member functions to be gen-
- erated and expanded in the file. When compiled, this causes the
- class Vector_double to be declared and defined. One drawback of
- the use of IMPLEMENT, however, is the fact that the entire class
- with all its member functions is generated and linked into the
- program image, even if the programmer only requires the use of
- two or three member functions. This problem can be avoided by the
- use of the COOL C++ Control Program (CCC) discussed below. Con-
- tinuing with the example above, the template for the Vector<type>
- class for doubles would expand to the following code:
-
- // predicate functions
- typedef int (*Vector_double_Predicate) (const double&, const double&);
- typedef Boolean (*Vector_double_Compare) (const double&, const double&);
-
-
- class Vector_double { // Parameterized Vector class
- private:
- double* v; // Vector of pointer to double
- int num_elements; // Element count
- int size; // Size of vector object
- public:
- Vector_double (); // Empty constructor
- Vector_double (int); // Constructor with size
- Vector_double (const Vector_double&); // Constructor with reference
- ~Vector_double (); // Destructor
- inline double& operator[](int n); // Operator[] overload for double
-
- ... // ... other member functions ...
- };
-
-
- // Overload operator []
- inline double& Vector_double::operator[] (int n) {
- return this->v[n];
- }
-
- // Constructor with size
- Vector_double::Vector_double (int n) {
- this->v = new double[n];
- this->size = n;
- this->num_elements = 0;
- }
-
- ... // ... other member functions ...
-
- Vector_double vs(30);
-
- Declarations of nested parameterized types and the use of non-
-
- -9-
- type arguments in a template definition are also supported. For
- example, it is possible to declare a vector of vectors of ints
- with Vector<Vector<int>>. In addition, a class template derived
- from another class template is supported, that is, a type parame-
- ter in one template class can be used to declare another class
- template of that type. For example, the COOL Association<T1,T2>
- class is a parameterized container class that takes two type
- arguments, T1 and T2. The header file for this class has the
- following templates.
-
- template <class T1, T2> Association {
- DECLARE Pair<T1, T2>; // Declare Pair object type
- DECLARE Vector<Pair<T1, T2>>; // Declare Vector of Pairs
- }
-
- ... // ...
- // Association<T1,T2> class definition here
-
-
-
- template <class T1, T2> Association {
- IMPLEMENT Pair<T1, T2>;
- IMPLEMENT Vector<Pair<T1, T2>>;
- }
-
- By using template in this manner, DECLARE for the
- Association<T1,T2> class invokes DECLARE on the correct types for
- the Pair<T1,T2> and Vector<Type> classes. Likewise, IMPLEMENT
- for the Association<T1,T2> class invokes IMPLEMENT for the
- Pair<T1,T2> and Vector<Type> classes.
-
- Non-type arguments as template parameters are used to provide
- guidelines to be used when a template is expanded. For example,
- the N_Tree<Node,Type,nchild> class in COOL takes as arguments a
- node type (either static or dynamic), a type specifying the
- value-type each node will hold, and an argument that specifies
- the number of initial subtrees (or children) each node is to
- have. The node argument is itself the name of a parameterized
- class and a nested parameterized template definition is automati-
- cally generated based upon the supplied type and number argu-
- ments. As such, a single template can be used to generate several
- different classes with different behaviors and features.
-
- 4.3. A Revised Programmer Interface: COOL C++ Control Program
- (CCC)
- The DECLARE and IMPLEMENT macros discussed above were the first
- programmer interface implemented for parameterized template sup-
- port. We soon discovered, however, that this macro expansion
- mechanism had two serious problems. First, the type over which a
- class was parameterized would have to support all operators used
- in the template, even if not applicable or needed. For example,
- the COOL List<Type> class has several member functions that use
- operator<. However, if what the programmer needs is a list of
- window objects and does not ever use List<Type> member functions
- that require operator<, compile-time errors from the offending
- functions that got macro-expanded are nevertheless generated.
- Second, With the simplistic linkers available on many operating
-
- -10-
- systems today, an application gets all of these member functions
- linked into the executable image. Typically, an application uses
- only a small percentage of the member functions of a parameter-
- ized class. The remaining unused member functions are useless
- overhead, increasing program size and memory requirements.
-
- A revised programmer interface for parameterized templates was
- implemented to resolve these problems and centers around a new
- program to be used as the main interface between the user and the
- preprocessor/compiler in a make file. This program, the COOL C++
- Control program (CCC), augments the standard CC script. For most
- operations, user options and command line arguments are passed
- straight through to the underlying CC program. However, when the
- -X option is specified, the CCC program goes to work in the fol-
- lowing manner. As Stroustrup[6] suggested, -X"Foo<Bar>" is used
- on the command line to indicate that the programmer wants to
- parameterize class Foo<Type> over some type Bar. Additional
- options for include file search path and a user-defined library
- archive are required as described below. CCC finds the header
- file(s) implementing class Foo and type Bar, then proceeds to
- define that type for the compiler. It then fractures the imple-
- mentation of this new type along template boundaries, placing
- each non-inline member function in a separate source file, com-
- piling it, and putting the resulting object file in a user-
- specified library archive. If a particular operator is not
- defined for the type over which the class is parameterized (as
- with the example of operator< above), a compile time error for
- that one file is generated. However, the remaining member func-
- tions, one in each fractured template, are still compiled and
- added to the user library.
-
- For each parameterized class in an application, CCC fractures the
- parameterized class definition along template boundaries, causing
- each template specifying a member function of the parameterized
- class to be compiled into a separate object file. These separate
- object files are then added to an application-specific object
- library. Since each member function is in its own object module
- in the library, only those member functions actually used in the
- application are linked into the final executable image. To use
- CCC, the programmer specifies a library name, one or more header
- files containing templates, and specific parameterized classes as
- command line arguments to CCC. Other arguments are passed on
- unchanged to the C++ compiler and system linker. A single invo-
- cation of CCC can either process a parameterized class type or
- compile a C++ source file, but not both. For example,
-
- CCC -lapp -c List.h String.h -X "List<String>"
-
- expands the template for a list of strings. The resulting object
- files from the fractured parameterized List<Type> class are
- stored in the library, libapp.a. The -c option is passed to the
- compiler to indicate that it should not continue with the link
- phase. The library archive libapp.a is added to the list of
- libraries specified in the make file to be searched during the
- link step.
-
- The net result is a library archive containing object files, each
-
- -11-
- implementing one member function for the parameterized class and
- type. This process solves the two problems identified above with
- the use of the macros DECLARE and IMPLEMENT. First, operators not
- defined for a type cause compile-time errors on that one file.
- Once a parameterized class has been implemented and provided in a
- library, compile errors will only occur when a type is selected
- that does not have all operators implemented. The user of the
- class will see these, and if the member function in question is
- required, s/he can add that necessary operator to the type class.
- Second, only member functions actually used in an application are
- linked into the final executable image.
-
- 4.4. Future Improvements to CCC
- CCC essentially provides a more sophisticated version of the
- IMPLEMENT macro discussed above. However, the programmer is still
- required to place the DECLARE macro in the appropriate files.
- One option under consideration to resolve this problem is the use
- of a command line switch similar to the +e0/+e1 switchs on the
- AT&T cfront translator. Under this scenario, the equivalent of
- the +e0 option would be used to declare the type for a parameter-
- ized class and generate the inline member functions (as the
- DECLARE macro does) but not to generate the remaining member
- functions. The programmer would use the equivalent of the +e1
- option on one source file to cause the remaining non-inline
- member functions to be generated and placed in a library archive.
-
- A second problem with CCC concerns the specification of nested
- parameterized classes. A programmer should be able to use
- -X"Vector<List<int>>" on the command line to specify creation of
- nested parameterized classes. Currently, CCC does not handle
- this case appropriately. A more sophisticated command line parser
- should be able to recognize and implement nested types before
- trying to expand the outer most parameterized class.
-
- 5. Conclusion
- The COOL macro facility provides a mechanism to implement signi-
- ficant language features and extensions for C++ that are unavail-
- able with current language implementations. The macro facility
- is implemented in an enhanced preprocessor that is both efficient
- and portable, thus allowing for delivery of enhanced language
- features on many platforms. This macro extension is at the heart
- of the parameterized templates functionality. CCC is used in
- place of the normal procedure for controlling the compilation
- process. It provides all of the functionality of the original CC
- program with additional support for the COOL preprocessor and
- parameterized type expansion. Finally, the preprocessor provides
- an ideal mechanism for quickly prototyping and testing additional
- language functions and syntax without requiring access to or
- modification of a compiler.
-
- 6. Status of COOL
- Texas Instruments has been using the enhanced macro facility and
- the implementation of parameterized templates internally on
- several projects for the last year. Many classes and programs
- have been successfully designed and implemented, taking full
- advantage of the power of parameterized templates and the
- enhanced macro facility. In particular, we have found that the
-
- -12-
- use of a class library supplying many basic parameterized con-
- tainer classes significantly increases the productivity of the
- programmer, enabling applications to be prototyped in a shorter
- time period than might otherwise be possible. COOL is currently
- up and running on a Sun SPARCstation 1 (TM) running SunOS (TM)
- 4.x, a PS/2 (TM) model 70 running SCO XENIX(r) 2.3, a PS/2 model 70
- running OS/2 1.1, and a MIPS running RISC/os 4.0. The SPARC and
- MIPS ports utilize the AT&T C++ translator (cfront) version 2.0
- and the XENIX and OS/2 ports utilize the Glockenspiel translator
- with the Microsoft C compiler.
-
- 7. References
- [1] Brian Kernighan and Dennis Richie, The C Programming
- Language, Second Edition, Printice-Hill, Englewood Cliffs,
- NJ, 1988.
- [2] Mary Fontana, Martin Neath and Lamott Oren, COOL - A C++
- Object-Oriented Library, Information Technology Group, Aus-
- tin, TX, Internal Original Issue January 1990.
- [3] Texas Instruments Incorporated, C++ Object-Oriented Library
- User's Manual, Information Technology Group, Austin, TX,
- Internal Original Issue January 1990.
- [4] AT&T Incorporated, C++ Language System Release 2.0, AT&T
- Product Reference Manual Select Code 307-146, 1989.
- [5] Guy L. Steele Jr, Common LISP: The Language, Second Edition,
- 1990.
- [6] Bjarne Stroustrup, Parameterized Types for C++, Proceedings
- of the USENIX C++ Conference, Denver, CO, October 17-21,
- 1988, pp. 1-18.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- _________________________
- SunOS and SPARCstation 1 are trademarks of Sun Mi-
- crosystems, Inc.
- PS/2 is a trademark of International Business Machines
- Corporation.
- XENIX is a registered trademark of Microsoft Corpora-
- tion.
-
- -13-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -14-
-
-