Boost logo

Boost :

From: Vesa Karvonen (vesa.karvonen_at_[hidden])
Date: 2001-07-19 04:43:04


[I tried to send a similar message yesterday, but somehow I seem to have
managed to completely misplace it. Hopefully I have not forgotten anything
important.]

First of all, this is not a review comment regarding the C++ Coding Coding
Guidelines (http://groups.yahoo.com/group/boost/files/coding_guidelines.html).
This is a proposal for addition into the Boost Library Requirements and
Guidelines (http://www.boost.org/more/lib_guide.htm).

The item 1.7. of the C++ Coding Guidelines mentions using forward declarations
for avoiding compile-time dependencies. I strongly agree with using forward
declarations for the purpose of avoiding compile-time dependencies. I would
like to see the practice of having a forward declaration header per library as
a requirement or at least a strong recommendation in Boost.

Forward declaration headers have two main purposes:
- facilitate reducing compile-time dependencies
- act as an effective form of documentation

In my experience, one forward declaration header per library is sufficient. If
a library changes so frequently or is so big that multiple forward declaration
headers seem necessary, then the library should usually be refactored. I've
been using forward declaration headers for many years and had nothing but
positive experience.

I feel that the lack of forward declaration headers in the standard library,
except for streams, is a significant cause of unnecessary problems and
confusion with the standard library.

Proposed requirement
====================

Every library that has forward declarable entities such as classes, must
contain a forward declaration header, that declares the public interface of
the library.

A forward declaration header contains declarations of public interface
classes, class templates, typedefs and possibly constants, and enumerations,
but not function prototypes, or class definitions, unless those are required
by interface declarations.

A forward declaration header must not include other headers except possibly
other forward declaration headers.

Examples of valid and invalid forward declaration header contents
=================================================================

// valid class declaration
struct interface_class;

// valid class template declaration
template<class p0, class p1>
struct inteface_class;

// invalid, because this implementation declaration is not needed
// by an interface declaration.
struct implementation_class;

// valid, because this implementation declaration is needed by an
// interface class template declaration.
struct default_implementation_class;

template<class p0, class p1 = default_implementation_class>
struct interface_class;

// valid enumerated constant definitions, because these are needed
// by an interface class template.
enum constants
{ constant_0
, constant_1
};

template<int p0 = constant_0, int p1 = constant_1>
struct interface_class;

[TBD: Add more examples.]

Proposed supporting guideline
=============================

It is recommended to name forward declaration headers consistently using one
of the following two forms depending on the organization of the library:

A) <boost/library_name_fwd.hpp>

   For top level libraries that do not have a dedicated directory.

B) <boost/library_name/fwd.hpp>

   For libraries that have a dedicated directory.

Rationale
=========

Forward declarations are very important for reducing compile-time dependencies
in C++ [Lakos].

Writing an external (outside of a library) forward declaration is difficult,
because it is necessary to open the namespace of the library.

Maintaining external forward declarations is difficult, because changes to a
library, such as changing default template parameters, that would otherwise
not break client code, can break client code that tries to forward declare
library entities.

A forward declaration header contains a concise listing of the public
interface of a library and often nothing, but the public interface. As such,
it is a very effective form of documentation that can, and usually does, make
it significantly easier to understand a library.

Making forward declaration headers an integral part of libraries conforms to
the underlying principle of the ODR rule (One Definition Rule) and the DRY
principle (Don't Repeat Yourself) [Hunt].

The problems caused by lack of forward declaration headers are similar to the
problems caused by copy-and-paste programming in general.

References and Bibliography
===========================

[Lakos] Lakos: Large Scale C++ Software Design
[Hunt] Hunt, Thomas: The Pragmatic Programmer
[Stroustrup] Stroustrup: The C++ Programming Language, 3rd. ed.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk