Boost Test Library: Execution Tools

Introduction
Benefits
Specifications
Sample Program
Header Implementation Option
Header boost/detail/catch_exceptions.hpp
Rationale
Design

Also see: Test Tools

Introduction

The Boost Test Library's Execution Tools provides a replacement main() function which calls a user-supplied cpp_main() function within a try block.. The library supplied main() then catches and reports exceptions, relieving users from messy error detection and reporting duties.

For use with the Execution Tools, the traditional Hello World program becomes:

#include <iostream>

int cpp_main( int, char *[] )  // note name
{
  std::cout << "Hello, world\n";
  return 0;
}

It really is that simple - just change the name of your initial function from main to cpp_main.  Do make sure the argc and arcv parameters are specified (although you don't have to name them if you don't use them).

When the above program executes, the output will be:

Hello, world
no errors detected

But what if some lower-level function had thrown a runtime_error with the message "big trouble"?  Then the output would look something like this:

** exception: std::runtime_error: big trouble
**** returning with error code 200
**********  errors detected; see stdout for details  ***********

And if a lower-level function had bubbled up a return code of 5, the output would look something like this:

**** returning with error code 5
**********  errors detected; see stdout for details  ***********

Note that the primary messages appear on stdout, while the final message appears on stderr.  This increases the visibility of error notification if stdout and stderr are directed to different devices or files.

Benefits

More uniform reporting of errors, particularly exceptions.

In production programs: 

More uniform error reporting is particularly useful for programs running unattended under control of scripts or batch files. Some operating systems pop up message boxes if an uncaught exception occurs, and this requires operator intervention. By converting such exceptions to non-zero program return codes, the library makes the program a better citizen.

More uniform reporting of errors isn't a benefit to some programs, particularly programs always run by hand by a knowledgeable person. So cpp_main() wouldn't be worth using in that environment.

In test programs:

More uniform error reporting is useful in test environments such as the boost regression tests. See the Test Tools, which uses cpp_main() as part of the test framework.

Specifications of the supplied main()

Uniformly detects and reports the occurrence of several types of errors, reducing the various errors to a uniform return value which is returned to the host environment.

There are two intended uses:

Requires: A user-supplied cpp_main() function with same interface as main().

Effects:

Call cpp_main( argc, argv ) in a try block.

Treat as errors:

Report errors to both cout (with details) and cerr (summary). Rationale: Detail error reporting goes to cout so that it is properly interlaced with other output, thus aiding error analysis. Summary goes to cerr in case cout is redirected.

Returns: non-zero if any error was detected.

Sample Program

cpp_main_example.cpp

Header Implementation Option

The library supplied main() function may be stored in an object library and linked into the final program just like any other supplied function.  If this is not convenient, the main() function may be supplied at compile time by including it as a header:

#include <boost/test/cpp_main.cpp>

Although this usage is unusual, it is quite useful in environments where it may be difficult or undesirable to link to an object library.

Header boost/detail/catch_exceptions.hpp

The actual exception catching code from the replacement main() function has been factored out into a separate header for those wishing to reuse this code.  It is not otherwise documented.

Rationale

The components of a C++ program may report user-detected errors in several ways, such as via a return value or throwing an exception.  System-detected errors such as dereferencing an invalid pointer are reported in other ways, totally operating system and compiler dependent. 

Yet many C++ programs, both production and test, must run in an environment where uniform reporting of errors is necessary.  For example, converting otherwise uncaught exceptions to non-zero program return codes allows many command line, script, or batch environments to continue processing in a controlled manner.  Even some GUI environments benefit from the unification of errors into program return codes.

Design

The Boost Test Library Design document describes the relationship between the Execution Tools and several other components.


© Beman Dawes 2001

Revised: 28 February, 2001