Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

C/C++

Libraries and "the One Right Way"


DEC91: PROGRAMMER'S BOOKSHELF

Any fool can turn out a book on the C runtime library--those functions such as printf(), strlen(), sqrt(), and setjmp()--and a quick trip to your local bookstore will reveal that many fools have. All it takes is the ability to copy, mistakes and all, the vendor's original documentation, and then serve up the resulting pointlessness as The Microsoft C Bible, The Complete Guide to Turbo C, or The Turbo C++ Programmer's Reference.

Our first book this month is a book on the C standard library that, wonder of wonders, has things you won't find in the manuals that came with your compiler. In fact, P.J. Plauger's The Standard C Library aims not so much to show how to use the C standard library, but to show how it is implemented. This is an incredible book! Instead of wasting paper just showing you how to call printf(), Plauger (who chaired the Library subcommittee of the ANSI C committee) shows you how to write printf--and scanf, malloc, sqrt, and every other function in the library approved by the ANSI and ISO standards for C.

Besides presenting about 9,000 lines of C code for a complete portable C runtime library, Plauger explains it all pretty much line-by-line, with special emphasis given to international considerations (multibyte character sets are given extensive coverage here), portability, testing, and handling of errors and oddities. For example, the chapter on <math.h> stresses the way in which even a seemingly trivial operation such as fabs (floating-point absolute value) is complicated and made nontrivial by the need to handle screwball values such as infinity and NaN (Not a Number). While authors of computer books frequently engage in "exercise left for the reader" cop-outs, Plauger seems to delight in tackling such nasties.

Certainly there are places where Plauger decides not to deal with an issue. The chapters explaining machine-specific facilities such as <signal.h> and <setjmp.h> are, in the interests of portability, somewhat vague. The implementation of realloc() does not try to expand a block in place. But Plauger is generally quite explicit about such limitations.

Some of the material in The Standard C Library has appeared in Plauger's monthly "Standard C" column in the C User's Journal. The book contains one chapter for each of the 15 .h files that make up the ANSI and ISO standard C library. Each chapter contains the following sections:

Within the "implementing" section, things seem explained in exactly the right order. However, it is extremely annoying that the chapters themselves are arranged in strictly alphabetical order. While the interdependencies of the 15 facilities that make up the C standard library probably make any ordering somewhat arbitrary, it seems absurd that, for instance, <math.h> and <float.h> are not treated together, and that the book begins with <assert.h> rather than with, say, <stdlib.h>. This is my only complaint about this otherwise superb book.

C++ 3.0

It is interesting to consider what isn't in the C standard library. While it contains generic searching and sorting facilities (bsearch() and qsort()), there is nothing for doing linked lists, hash tables, or circular buffers. The manipulation of such structures is simply too difficult to "library-ize." Yet, not having these available as components just as standard as printf() and strlen() is a shocking waste.

The C++ programming language is in many ways an attempt to solve this large problem. In C++, generic facilities such as linked lists are much more amenable to being put in a library that programmers can really use with the same ease that they use strlen(). But to make the masses of programmers switch from C, C++ needs to provide immediately tangible benefits, such as actual, inexpensive, shrinkwrapped libraries, rather than the mere ability to create such libraries.

Reading the new second edition of Stroustrup's The C++ Programming Language, I for the first time felt that this might really happen. The overall theme of the many changes to C++, Stroustrup notes, has been to make it "a better language for writing and using libraries." Libraries really are the key to the whole business. Some of the changes in C++, such as multiple inheritance, are truly of interest only to connoisseurs of object-oriented design. But others, such as templates, seem like such a big win that some day--when there are several inexpensive C++ 3.0 compilers available--not using C++ may seem as conservative and hidebound as refusing to use function prototypes in C would seem today.

Whether or not you use C++--and, let's face it, very little commercial software shipping today has been written in C++--you owe it to yourself to get the new edition of Stroustrup's book. (Note that this is the second edition of The C++ Programming Language, and not the hardcover Annotated C++ Reference Manual, which was reviewed in the May 1991 DDJ.) Not only is the second edition well written and quite readable by the average C programmer, but it covers many topics of wide interest.

In particular, The C++ Programming Language now contains three chapters (over 100 pages) on general issues of design. This includes such topics as the development cycle, management, reuse, hybrid design, components, and the design of libraries. Throughout, Stroustrup is concerned with making the right compromises between conflicting goals. As he notes several times in the book, "This reflects my view that there is no 'one right way.'"

That sounds trite, but when you think about it, many programmers in fact act as if there were such a thing as "the right way," and as if the goal of software design were to come up with "elegant" solutions. Wrong! Stroustrup clearly designed C++ itself as a series of trade-offs. This is exactly why it, rather than "purer" languages such as Smalltalk, actually has a chance of becoming a tool that's used by masses of programmers.

Two other new chapters discuss the most recent additions to C++: templates and exceptions. Proper exception handling is required by anyone building or using industrial-strength libraries. The new exception-handling mechanism in C++ 3.0 (which adds the keywords try, catch, and throw) feels much too complex, but Stroustrup's chapter on this subject is brilliant. Any programmer even remotely interested in the three Es--errors, events, and exceptions--will want to read Stroustrup's discussion of this subject.

The chapter on templates presents what is probably the most exciting new facility of C++ 3.0. Templates allow very generic facilities, such as linked lists or sort procedures, to be defined without being tied down to a specific class. While providing many of the benefits of typeless languages, templates do not undermine static type checking or runtime efficiency.

This sounds rather vague, so see the stack template in Example 1, which defines a stack as a completely abstract data type, with no mention of whether it is a stack of ints, chars, or widgets. That gets decided when someone creates a stack which uses this same declaration to create, for example, a stack of ints and a stack of chars (as shown in Example 2). In essence, templates provide all the typeless flexibility of preprocessor macros, but without the many problems associated with macros (naturally, templates do introduce some new problems).

Example 1: A stack template in C++ 3.0

  // stack.h

  template<class=T> class stack

  {

      T *V, *p;
      int sz;

  public:

      // all the following functions are inline
      stack(int s)        { v = p = new T[sz = s]; }
      -stack()            { delete[] v; }
      void push (T a)     { *p++ = a; }
      T pop()             { return *--p; }
      int size() const    { return p-v; }
  }

Example 2: Creating two different classes of stack from the same template

  #include <iostream.h>
  #include "stack.h"

  main()
  {
      stack<int>  si(100);           // stack of 100 ints
      stack<char> sc(100);           // stack of 100 chars

      for (int i=0; i<10; i++)
      {
          si.push(i);
          sc.push(i);
      }

      while (si.size())              // pop everything and
          cout << si.pop() << ' ' ;  // display it
      cout << '\n' ;
  }

The implications of templates for library building should be clear, or at least they will be, once compilers are available to implement templates. I used a beta version of such a forthcoming C++ compiler and was particularly impressed at how templates interact nicely with the C++ inline facility; the assembly language output from Example 2 was exactly what one would have achieved doing all this by hand in C. Example 3, for instance, shows what the statement si.push(i) became.

Example 3: Assembly language output from Example 2

  mov bx, word ptr [si.p]
  mov ax, word ptr [i]
  mov word ptr [bx], ax   ; *p = i
  add word ptr [si.p], 2  ; p += sizeof(int)

With the language described in Stroustrup's second edition, it truly seems possible that we could one day have extensive libraries of ready-to-use, high-level classes, that are as easy and intuitive to use and as efficient as strlen() is today. Yet this will require not only that C++ provide the right set of features, but that the designers of these libraries show some of the same level-headedness that Stroustrup reveals in his book. "The conviction that there is no one right way permeates the design of C++." In this spirit, future C++ libraries might have to look a lot more like the present C standard library than their designers might like.


Copyright © 1991, Dr. Dobb's Journal


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.