Columns


Stepping Up To C++

C++ at CD Registration

Dan Saks


Dan Saks is the president of Saks & Associates, which offers consulting and training in C++ and C. He is secretary of the ANSI and ISO C++ committees. Dan is coauthor of C++ Programming Guidelines, and codeveloper of the Plum Hall Validation Suite for C++ (both with Thomas Plum). You can reach him at 393 Leander Dr., Springfield OH, 45504-4906, by phone at (513)324-3601, or electronically at dsaks@wittenberg.edu.

As P.J. Plauger recently reported in his "Editor's Forum," CUJ, September 1994, the draft C++ standard has reached a major milestone on its way to becoming a bona fide standard. This past July, the joint ANSI and ISO C++ standards committees voted to submit the latest draft for registration as a committee draft (CD). CD registration is the first of three ballots that a draft must pass before it becomes an international standard (IS).

As Plauger explained, the significance of this stage (aside from simply showing progress) is that it's supposed to be the point at which all the key features of the language are in place. As such, this is probably a good time to look back and see how the language has changed over the past few years.

Who's Standardizing What?

It's hard to talk about programming language standards without bandying about acronyms like ANSI and ISO, or arcane codenames like X3J16 or WG21. Although you clearly don't need to understand these terms to program competently in C++, I expect that many of you are at least a little interested in understanding the forces that shape your destiny.

Table 1 contains a handy quick reference guide to standards organizations and committees affecting C and C++. You may find it helptul to refer to the table from time to time.

ANSI (pronounced "AN-see") stands for the American National Standards Institute. ANSI is a trade association that sets standards for industrial products and processes. ANSI standards cover a wide assortment of products such as bar codes, bicycle helmets, heating and air conditioning equipment, and plywood. ANSI is not a US government agency and its standards are not in and of themselves binding by law. However, a government agency may adopt an ANSI standard for regulatory or procurement purposes, thus entwining that standard with laws.

ANSI doesn't actually write standards; it establishes procedures for writing and approving standards, and then delegates most of the work to industry-specific standards committees. X3 is the ANSI-accredited committee that administers standards development for information processing systems (which includes programming languages). X3 operates out of the headquarters of CBEMA, the Computer and Business Equipment Manufacturer's Association. CBEMA (pronounced "see-BEE-ma") provides funding and staffing for X3's activities.

X3 in turn establishes technical committees to develop specific standards. X3 has chartered, among others, X3J11 and X3J16 to develop the ANSI standards for C and C++, respectively. X3J16 started working in early 1990, and has been meeting three times a year ever since.

ANSI has counterparts in other nations, such as AFNOR (France), BSI (UK), DIN (Germany), JTSC (Japan), SCC (Canada), and many others. (To the rest of the world, please pardon me for not listing your national standards body.) These national standards bodies are members of ISO ("I-so"), the International Organization for Standardization. As with its members, ISO doesn't write standards, but rather charters committees to establish standards according to ISO procedures. ISO standards are not laws, but they have become the basis for international treaties, and so should not be taken lightly.

ISO works cooperatively with yet another standards group, IEC, the International Electrotechnical Commission. ISO and IEC formed a joint technical committee, JTC1, to standardize information technology. JTC1's subcommittee SC22 oversees the development of international programming language standards.

The international counterpart of an ANSI technical subcommittee like X3J16 is called a "working group." WG14 and WG21 are the SC22 working groups responsible for the international C and c++ standards, respectively. (WG21's fully-qualified name is ISO/IEC JTC1/SC22/WG21.)

WG21 has been meeting jointly with X3J16 since the summer of 1991. The joint committees are working to produce a single document that, if all goes well, will become both the ANSI and ISO standards for C++. I often refer to the joint committees as a singular entity (the "joint committee" with no "s") or as WG21+X3J16.

Base Documents

Rather than write the C++ standard from scratch, X3J16 started by adopting the AT&T C++ Product Reference Manual (the PRM) version 2.1 as the base document, that is, as the initial working draft. C++ programmers are not as familiar with the PRM as they are with the Annotated C++ Reference Manual (the ARM)[1]. The ARM is a textbook that includes a version of the PRM along with annotations and commentary that elaborate the language description, explain many language design decisions, and suggest implementation techniques. The ARM also includes chapters on templates and exceptions, which the PRM does not.

Thus, strictly speaking, the ARM is not the base document. However, X3J16's first decisions eliminated most of the differences between the draft and the ARM (aside from the annotations and commentary). Therefore, for all practical purposes, the initial draft standard was based on the ARM, and so it's fair to call the ARM the base document.

X3J16 selected the C standard as its second base document. Over the years, the committee has mined the C standard for passages describing parts of C that are supposed to be the same, or nearly the same, in C++. For example, the ARM does not include a grammar for the lexical tokens of C++ (constructs such as identifiers and literals). The C++ draft standard now incorporates the lexical grammar from the C standard. Similarly, the C++ draft's description of the preprocessor is now nearly identical to the one in the C standard. Nonetheless, the overall structure of the C++ draft still largely resembles that of the ARM.

Occasionally, I receive requests for information about or copies of the "C++ 3.0 standard" or something similar. There is no such thing. I think such questions arise because before there was a draft standard, compiler vendors used to claim compatibility with numbered versions of AT&T's C++ compiler.

C++, like C, began at AT&T Bell Labs. AT&T started distributing a C++ compiler called cfront in the mid-1980s. For a few years, it was the only C++ compiler around. For several more years, cfront remained the de facto standard for C++ compilers. Vendors of the first non-AT&T C++ compilers typically described the features their compilers supported by comparison with AT&T's product. This practice continued through the release of cfront 3.0 in 1991, even after X3J16 had been at work for a couple of years. Comparisons with cfront 3.0 are now pass, but the confusion apparently still lingers.

In short, there is not yet a C++ standard, but there is a draft C++ standard inching its way toward formal acceptance several years from now. That draft is based on, and still bears a strong resemblance to, the ARM, but it has also gone well beyond the ARM in many ways. What follows is a summary of the changes in the language wrought by standardization. But first...

What About Libraries?

Except for mentioning a few header files and functions, the ARM does not describe any run-time library accompanying a C++ implementation. From the beginning, X3J16 agreed that any acceptable C++ language standard must include a library. The current C++ draft includes a fairly extensive library, including language support functions, iostreams, complex arithmetic, and an adaption of the Standard C library. The draft also contains a variety of data structures, such as strings, dynamic arrays, and assorted container classes, most of which are provided as templates.

I shall focus my attentions on the language itself, and defer to my colleagues at CUJ in describing the C++ library. (See Chuck Allison's column, "Code Capsules: The Standard C++ Library," CUJ, December 1994.) You can find even greater detail on the library in P.J. Plauger's CUJ columns over the last year and well into the future, or in his most recent book [2].

Language Changes

The joint committee has made a lot of changes in the C++ language definition. Many of the changes are substantive; they change the syntactic structure and/or the semantic interpretation of the C++ language itself. Other changes are just editorial — they are changes in the description of the C++ language, not in the C++ language itself. The following lists omit changes that I believe are purely editorial.

To give you a better sense of the nature of the substantive changes, I've grouped them into four broad categories:

This is not a hard-and-fast classification scheme, and my judgments about what goes where are admittedly subjective. But hey, it's my column.

Major Extensions

The major extensions are:

Templates are a translation-time facility for writing generic functions and classes in terms of unspecified types. For example,

template <class T>
void swap(T &a, T &b)
   {
   T t = a;
   a = b;
   b = t;
   }
defines a template for a function that will swap (exchange the values stored in) two objects of arbitrary type T. I described function templates in some detail in "Recent Extensions to C++," CUJ, June 1993. I devoted my entire column last month to template classes ("Designing Generic Container Classes, Part 6: Templates," CUJ, December 1994). You will find a lengthy discussion and numerous examples of templates in
[3] and [4]

Exception handling is a facility for orderly recovery from exceptional (typically erroneous) events during program execution. C++ exception handlers can only handle synchronous events — the kinds of events that can be expressed as conditional expressions (for use in if or while statements or in assert macro calls). Exception handlers cannot intercept asynchronous events, such as device interrupts or hardware faults, which are better handled as signals.

C++ provides exception handling through additional flow structures and library functions. A try-block is a compound statement (a sequence of statements enclosed in brackets) followed by a sequence of one or more handlers, also known as catch clauses. For example,

try
   {
   // do something
   }
catch (const char *s)
   {
   // catch an error
   }
is a try-block. The handlers "catch" exceptions "thrown" by throw expressions executed in the compound statement or in functions called from within the compound statement, For example, executing

throw "something happened";
throws an exception that will be caught by the catch clause above. The throw terminates every active function invoked from the try-block and transfers control to the catch clause. Presumably, the catch clause handles the exception somehow.

For much more detail on exceptions see Chuck Allison's "Code Capsules: C++ Exceptions," CUJ, July 1994, as well as [3] and [4].

Run-time type information (RTTI) is a facility for querying the dynamic type of a polymorphic object. A polymorphic object is an object whose class has at least one virtual function. An expression that refers to a polymorphic object has both a static type and a dynamic type, which may be different. For example, given:

class B
   {
public:
   virtual void f();
   ...
   };
class D: public B
   {
   ...
   };
B*pb = new D;
then *pb is a polymorphic object with static (declared) type B but dynamic (run-time) type D.

Using RTTI, you can query an object with a given static type to determine if it has a particular dynamic type. One form of query is an expression such as

if (typeid(*pb) == typeid(D))
...
You can also try to convert pb to a D * using

D *pd = dynamic_cast<D *>(pb);
which sets pd to 0 (a null pointer) if pb does not point to an object whose dynamic type is either D or a type derived from D.

For a little more detail on RTTI see Chuck Allison's "Code Capsules: Conversions and Casts," CUJ, September 1994. For much more detail, see [4].

Namespaces offer a mechanism for adding qualifiers to global names in the hope of reducing global name conflicts. Global name conflicts typically occur when a program attempts to use two different libraries that use the same global name but for different purposes. For example, libA.h might declare

class status { ... };
but libB.h might declare

enum status { ... };
A translation unit that tries to include both libA.h and libB.h will run up against compilation errors.

Wrapping these global names in separate namespaces eliminates the conflicts. In libA.h, you write:

namespace A
   {
   class status
   { ... };
   ...
   };
and in libB.h you write:

namespace B
   {
   enum status { ... };
   ...
   };
A program that uses both libraries must refer to a status type by its explicitly-qualified name, i.e., as either A::status or B::status. If you would like the unqualified name status to mean A::status by default, you can write

using namespace A;
Then you must still refer to B::status by its fully-qualified name. Writing both

using namespace A;
using namespace B;
reintroduces the name conflict.

Chuck Allison's "Code Capsules: Visibility in C++," CUJ, May 1994 has more discussion of namespaces. [4] has even more.

Minor Enhancements

In addition to the major extensions, the draft C++ standard includes numerous minor enhancements:

I covered the first five of these minor enhancements in "Recent Extensions to C++," CUJ, June 1993.
[4] covers some the others. I'll get around to covering all of them in an upcoming column.

All of the extensions and enhancements have added a lot of keywords to C++. See Table 2 for the complete list of C++ keywords, as listed in the current draft standard.

Changes in Meaning

The C++ draft also changes the behavior of numerous constructs from their previous behaviors specified by the ARM. Some changes simply prohibit features that were never intended to be, yet somehow slipped into some implementations. Other changes actually just change some constructs with explicitly-defined behavior to have different behavior. Roll with it.

Here are the changes:

Clarifications

The ARM left a lot unsaid. The committee has been trying to fill in the details. Here's the summary of most of the issues clarified so far:

As you can see, we at CUJ have plenty to write about for years to come.

Meeting Dates, Etc.

WG21+X3J16 will meet three times in 1995:

If you would like to participate in the standards process as a member of X3J16, contact the vice-chair:

Jose'e Lajoie
IBM Canada Laboratory
844 Don Mills Rd.
North York, Ontario M3C
1V7 Canada
(416)448-2734
josee@vnet.ibm.com

References

[1] Margaret A. Ellis and Bjarne Stroustrup. The Annotated C++ Reference Manual (Addison-Wesley, 1990).

[2] P.J. Plauger. The Draft Standard C++ Library (Prentice-Hall, 1995).

[3] Bjarne Stroustrup. The C++ Programming Language, 2nd. ed. (Addison-Wesley, 1991).

[4] Bjarne Stroustrup. The Design and Evolution of C++ (Addison-Wesley, 1994).