libcwd: The C++ Debugging Support Library - Tutorial
Author: Carlo Wood

| The C++ Debugging Support Library By Carlo Wood, ©1999 - 2003.

## Tutorial 1: Hello World

The smallest C++ program that prints «Hello World» as debug output to `cerr` is:

[download]

Compile as: g++ -g -DCWDEBUG hello_world.cc -lcwd -o hello_world

    // These four lines should actually be part of a custom "sys.h" file.  See tutorial 2.
    #ifndef _GNU_SOURCE                     // Already defined by g++ 3.0 and higher.
    #define _GNU_SOURCE                     // This must be defined before including <libcwd/sys.h>
    #endif
    #include <libcwd/sys.h>                 // This must be the first header file
    // This line should actually be part of a custom "debug.h" file.  See tutorial 2.
    #include <libcwd/debug.h>

    int main(void)
    {
      Debug( dc::notice.on() );             // Turn on the NOTICE Debug Channel.
      Debug( libcw_do.on() );               // Turn on the default Debug Object.

      Dout(dc::notice, "Hello World");

      return 0;
    }

Each of the lines of code in this first example program are explained below:

### `#define _GNU_SOURCE`

This define is necessary to tell the system headers that you want to use the GNU extensions (see /usr/include/features.h). In order to make you explicitely aware of the fact that it is defined, libcwd does not define this macro itself (which it could do inside <libcwd/sys.h>), but forces you to define it when using libcwd. Note that you only really have to define it when you compiled libcwd with threading support. If you do not define this macro and libcwd needs it, then you will get a compile error in <libcwd/sys.h> telling you so.

#### FAQ

- Won't this define make my code non-portable?

### `#include <libcwd/sys.h>`

This must be the very first header file that is included; even before system header files. Every source file that includes other libcwd headers must include it.

#### FAQ

- Why?
- Why do I need to type "`libcwd/sys.h`" and not just "`sys.h`"?

### `#include <libcwd/debug.h>`

This header file contains all definitions and declarations that are needed for debug output. For example, it defines the macros `Debug` and `Dout` and declares the debug object `libcw_do` and the debug channel `dc::notice`.

#### FAQ

- What is defined exactly in `libcwd/debug.h`?
- Why are you using macros for `Debug` and `Dout`?

### `Debug( dc::notice.on() );`

This turns on the Debug Channel `dc::notice`. Without this line, the code `Dout(dc::notice, "Hello World")` would output nothing: all Debug Channels are off by default, at start up.

#### FAQ

- Why do I need to type the `Debug( )` around it?
- Which Debug Channels exist? Can I make my own?
- Can I turn Debug Channels off again? Can I do that recursively?
- Why do you call it a Debug Channel? What is a Debug Channel?

### `Debug( libcw_do.on() );`

This turns on the Debug Object `libcw_do`. Without this line, the code `Dout(dc::notice, "Hello World")` would output nothing: all Debug Objects are off by default, at start up.

A Debug Object is related to exactly one `ostream`. `Libcwd` defines only one Debug Object by itself (being `libcw_do`), this is enough for most applications. The default ostream is `cerr`. Using the macro `Dout` causes debug output to be written to `libcw_do`.

#### FAQ

- Why do I need to type the `Debug( )` around it?
- Can I make my own Debug Object?
- Can I turn Debug Objects off again? Can I do that recursively?
- How do I set a new `ostream` for a given Debug Object?
- Why are Debug Objects turned off at creation?
- Why do you turn on the debug object after you enable a debug channel, why not the other way around?
- Why do you call it a Debug Object? What is a Debug Object?

### `Dout(dc::notice, "Hello World");`

This outputs "Hello World" to the `ostream` currently related to `libcw_do` provided that the Debug Channel `dc::notice` is turned on.

Output is written as if everything in the second field of the macro `Dout` is written to an ostream; It is "equivalent" with: `cerr << "Hello World" << '\n';`

#### FAQ

- Why is `Dout` a macro and not a template?
- Do I need to type that semi-colon after the macro? Why isn't it part of the macro?
- I made my own Debug Object, can I still use `Dout`?
- Is the second field of the macro still evaluated when the Debug Channel and/or Debug Object are turned off?
- Can I suppress that new-line character?