25B. Modules


Modules

Only a small computer program is written as a single file. Larger pieces of software are normally broken into separate modules, each module in one file. When you add more code to software, instead of making the modules larger, you add more modules. As a rule of thumb, modules are shorter than 1000 lines, with much smaller modules common. Modules are critical for working in teams. Imagine several programmers working on the same file at the same time.


Module interfaces

Replaceable parts have been a boon to modern life. If you get a flat tire, you can get another tire that fits your wheel perfectly. If you get angry and smash your computer monitor into shards, you can get another that has a cable that exactly fits a plug on your computer.

Modules are the replaceable parts of software. But that idea only works if each module has a clear interface, so that a module plugs into a larger piece of software and fits it exactly. The interface of module M tells which functions, types, constants and possibly variables M defines and exports to other modules.

More precisely, the interface tells the things that M must define. There is no prohibition on M defining things that are not mentioned in the interface. But if you replace M with another version, there is no guarantee that the new M defines anything beyond the official interface. Therefore, other modules must only use thing that are part of M 's interface.


Header files

Each C++ module A.cpp has an interface that is described in a header file A.h. Typically, a header file contains:

that A.cpp promises to define. To describe a constant or variable in a header file, simply write extern in front of its declaration. For example, if A.h says

  extern const double pi;
  extern int traceLevel;
then A.cpp must declare constant pi  and integer variable traceLevel; additionally, because they are declared in A.h, pi  and traceLevel  are part of the interface of A.cpp.

Module A.cpp must include its own header file, A.h.


Including header files

When you include a library module, such as cstdio, you write

  #include <cstdio>
The < and > signs indicate that cstdio is found in the standard library. If, on the other hand, you write
  #include "stuff.h"
the quote marks indicate that file stuff.h is found in the same directory as the file that contains this #include line.


Standards and a flaw in header files

Two facts should be obvious at this point.

There is a flaw in header files, at least in the way we will use them. A type definition in a header file provides more information than it should. Suppose that module queue.cpp exports type Queue; that is, queue.cpp guarantees to define a type called Queue. But only the fact that Queue is defined is exported, not how Queue is defined. Now suppose that queue.h says

  typedef int* Queue;
That tells exactly how type Queue is defined. It provides too much information. As far at the C++ compiler is concerned, other modules can make use of the knowledge that Queue is the same as int*. That can cause problems later. If queue.cpp and queue.h are replaced in a way that type Queue is defined differently, the software will not longer compile.

There is not much you can do about that. With some exceptions that we will see, if you define a type in C++, you are required to say how it is defined. But you can write a comment making it clear that Queue is exported but its definition is not.


Exercises

  1. What is the purpose of a header file? Answer

  2. How does a C++ program P.cpp include header file tools.h that is in the same directory as P.cpp? Answer

  3. What is the difference between

      #include "tools.h"
    
    and
      #include <tools.h>
    
    Answer