Back to TOC Book Review


C Interfaces and Implementations

reviewed by Donald Bryson


Title: C Interfaces and Implementations: Techniques for Creating Reusable Software
Author: David R. Hanson
Publisher: Addison Wesley Longman, 1997
Pages: 519
ISBN: 0-201-49841-3
Price: $40.83

Click here for cover

With only a quick glance at this book in the gorged shelves of a bookstore, you'll never know what it's about. The title doesn't lure your wallet from your hip. This book might be destined to be another bookshelf wallflower, unbought on the store shelf. Obvious titles would be "Creating Your Own Libraries in C" or "Build Your Own API." Instead, Addison-Wesley released the book with a title that will make most of us think it's just another GUI book.

While the title might be a marketing disaster, it does underscore the greatest strength of the book: Hanson teaches the separation of coding from the specification of a library. Hanson calls specifications the interface and he calls coding the implementation. The interface is the published documentation of what an API does. The implementation is the actual coding of the library in a particular environment. Hanson emphasizes the correct way to craft and use libraries — write code to fit the specifications perfectly and then limit your use of the library to what you can know from the specifications.

Forget everything you know about the internal workings of any library that you use. Undocumented features change on a whim and cause coupling bugs. Coupling occurs when you use an undocumented and unspecified aspect of an API and that aspect changes. It is called coupling because you have coupled your application logic to a particular implementation and not to the interface.

This book discusses five types of libraries: fundamentals, data structures, strings, math, and threads. The fundamentals section has a very good discussion of the three basic types of errors: user errors, checked run-time errors, and exceptions. This section also discusses memory management and assertions. There are also modules for dealing with errors and memory management.

Hanson also includes seven useful modules for maintaining and manipulating the following data structures: lists, tables, sets, dynamic arrays, sequences, rings, and bit vectors. A list is a single-linked collection of pointers; both rings and sequences are double-linked collections of pointers. The main difference between a ring and a sequence is that a ring allows values to be added or deleted anywhere. A sequence is contracted or expanded by removing values only from the front or back. The set and bit-vector modules are similar; however, the bit-vector module assumes a distinct universe of items. The set module, as defined in the book, does not. The table module includes useful functions for manipulating key-value pairs.

There are four modules for dealing with strings: modules for atoms, for formatting, for low-level string manipulation, and high-level string manipulation. An atom is a pointer to an area of memory, usually a null-terminated string. The formatting module has three advantages over the standard sprintf routine: the conversion specifiers are user expandable, the output routine can changed, and it will not attempt to store output larger than the receiving array. The low-level string routines deal with null-terminated strings, and the high-level routines use a string structure that is not null-terminated.

Hanson includes three modules for math functions: the extended-precision arithmetic module, the arbitrary-precision module, and the multiple-precision module. He uses the arbitrary precision module to demonstrate a useful library building technique — that of building one module from another. The arbitrary precision module uses functions found in the extended-precision module.

The last three modules in the book deal with multithreaded programs: Thread, Chan, and Sem. The Thread module creates and maintains threads; the Sem module creates and maintains semaphores; and the Chan module enables communication between threads. The chapter on threads contains a very good explanation of threads, thread-safe functions, and reentrant functions. (A nonreentrant function is one that changes global variables or uses static variables.) A thread-safe function is polite when accessing shared data and notifies other functions that it is doing so.

Target Audience

The book is well organized, accurate, and has a useful "further reading" section at the end of each chapter. The exercises at the end of each chapter are challenging. The topics are well covered and it will make a good textbook for sophomore to first-year graduate level courses. The tone of the book is very academic, but it is clearly written. It can also serve as a review or as an introduction to creating APIs for those of us who seek food and shelter instead of grades.

The source code is helpful, but I would prefer standard program listings. Hanson uses what he refers to as literate program formatting. The listings in the book substitute prose for comment and #include statements. This format isn't too distracting, but does require extra effort to translate while reading.

The APIs are actually production quality C libraries, but don't buy the book just for them. The C++ Standard Template Library does many of the same things as Hanson's APIs. Also, if you still need C APIs, you can download all of Hanson's via anonymous ftp at ftp.cs.princeton.edu in pub/packages/cii.

Why would you want this book? When I was learning my first language, someone gave me advice that I didn't understand: don't worry about the syntax, worry about the art. After a decade of surviving new buzzwords, compilers, operating systems, libraries, and languages — I finally understand. Syntax takes two minutes to look-up; art takes a lifetime to master. It is the art alone that is the constant. It is the art alone that constitutes the creative and the skillful. The art is what Hanson is teaching.

If, as some in the media predict, we all start programming exclusively in Java one day, the two main lessons in this book will still serve you well: build your black boxes strong and black as night. Build them strong enough to hold the weight of your application, and black enough to keep the novice out of their cogs.

All programming languages support some type of black box. These black boxes are called libraries in C and classes in C++. The syntax, metaphors, and mindset of languages may be different; however, the art of making strong black boxes will always be the same. So, when you pass this wallflower book in the bookstore, take a good look at it. We may all be using one of your APIs someday. o

Don Bryson is president and CEO of Quality Software Solutions, Inc., and is the author of TimeClock, TimeClock Lyte, DbDelta, and the Property Presentation System.