### Tracing Exceptions

The ITrace class provides a set of facilities that allow you to put trace statements in your code. When an exception is thrown, trace records are output with information about the exception. The ITrace class allows you to send trace output to standard output or to capture it in a file.

By defining certain macros, you can selectively turn tracing on and off. There are three special trace macros:

- IC_TRACE_RUNTIME
- IC_TRACE_DEVELOP
- IC_TRACE_ALL

By defining or not defining these macros, you can specify whether or not the trace macros are expanded, and thus whether or not your program produces trace output.

If IC_TRACE_RUNTIME is defined, the following macros are expanded:

IMODTRACE_RUNTIME
  This macro takes one argument that is the name of the current module. It creates an ITrace object using the module name as the name of the trace and the current line number as the line number.
IFUNCTRACE_RUNTIME
  This macro takes no arguments. It creates an ITrace object using the function name as the name of the trace and the current line number as the line number.
ITRACE_RUNTIME
  This macro takes a single argument. This argument is written to the trace location.

If IC_TRACE_DEVELOP is defined, all of the macros that are expanded when IC_TRACE_RUNTIME is defined are also expanded. In addition, the following macros are expanded:

IMODTRACE_DEVELOP
  This macro takes one argument. Typically you use the argument to name the current module. This macro creates an ITrace object using the module name as the name of the trace and the current line number as the line number.
IFUNCTRACE_DEVELOP
  This macro takes no arguments. It creates an ITrace object using the function name as the name of the trace and the current line number as the line number.
ITRACE_DEVELOP
  This macro takes a single argument. This argument is written to the trace location.

If IC_TRACE_ALL is defined, all of the macros that are expanded when IC_TRACE_DEVELOP is defined are also expanded. In addition, the following macros are expanded:

IMODTRACE_ALL
IFUNCTRACE_ALL
ITRACE_ALL

The following code shows one way that you could use the trace macros to produce trace output for your programs. In this code, the macros IFUNCTRACE_DEVELOP and ITRACE_DEVELOP are used to create trace statements that indicate that the flow of control has passed through the functions openFile and getFirstChar.

    // Producing trace output with the ITrace class

    #define IC_TRACE_DEVELOP

    #include <iostream.h>
    #include <fstream.h>
    #include <iexcept.hpp>
    #include <itrace.hpp>

    void openFile(fstream& fs, char *filename){
       IFUNCTRACE_DEVELOP();
       fs.open(filename, ios::in);
       ITRACE_DEVELOP("after open statement");
       }

    char getFirstChar(fstream& fs) {
       char c;
       IFUNCTRACE_DEVELOP();
       fs.get(c);
       ITRACE_DEVELOP("after get statement");
       return c;
       }

    void main() {
       char c;
       char * filename = "source.dat";
       fstream fs;
    //
    // static functions to enable tracing and direct
    // tracing output to standard output
    //
       ITrace::enableTrace();
       ITrace::writeToStandardOutput();
       openFile(fs, filename);
       c = getFirstChar(fs);
       cout << "Here is first character: " << c << endl;
       }

Notice that, in this code, the static functions enableTrace and writeToStandardOutput are used to enable tracing and to direct the trace output to standard output.

Because the macro IC_TRACE_DEVELOP is defined, the trace macros produce trace output. In addition, the trace output has been explicitly directed to standard output, so the output of the code looks like this:

    +openFile(fstream&,char*)
      >after open statement
    -openFile(fstream&,char*)
    +getFirstChar(fstream&)
      >after get statement
    -getFirstChar(fstream&)
    Here is first character: t

Suppose that you wanted to turn off the trace output in this program. One way to do it is to modify the code so that the macro IC_TRACE_DEVELOP is not defined. If you do this, the trace macros are not expanded, and no trace output is produced. The output of this code with IC_TRACE_DEVELOP not defined looks like this:

    Here is first character: t

Using Throw Macros
Interpreting Exceptions
Using Assertion Macros
Using try and catch
Rethrowing Exceptions
Deriving Your Own Exceptions

The Exceptions Mechanism
Using Exceptions