www.digitalmars.com [Home] [Search] [Contents]

__debug Statement

Two versions of a program are typically written, a debug version and a release version. The debug version contains extra code to do things like extra checking, printing out the values of variables, etc. Unfortunately, C/C++ provides no language support for this, it all must be done with the preprocessor.

The obvious way to do it is bracket the code with:

	#ifdef DEBUG
		...
	#else
		...
	#endif
but it winds up looking clumsy. Various attempts are made to clean up the look by using macros, but macros run afoul of 1) poor support for multiline macros 2) functions with variable numbers of arguments like printf() are problematic and 3) whether {} or () are used is problematic and inconsistent.

The solution is to build the syntax right into the language. Hence the debug statement:

    debug_statement ::=
	    "__debug" [ "(" expression ")" ] statement [ "else" statement ]
Debug statements are compiled in when the -D switch is thrown, else they are simply parsed and thrown away without doing a semantic check.

The debug statement takes on several forms:

    __debug printf("Blah, blah\n");
will only compile in the printf if -D is thrown. Alternatively,
    __debug
    {
	printf("Blah, blah\n");
    }
will do the same thing. A debug statement without a (expression) and without { } does not introduce a new scope,
    __debug int i = 7;
    __debug printf("i = %d\n", i);
whereas:
    __debug { int i = 7; }
    __debug printf("i = %d\n", i);	// error, i undefined
An else clause can be added:
    __debug
    {
	printf("Debug version\n");
    }
    else
    {
	printf("Release version\n");
    }
Note: Whether the else clause is a good idea or not is debatable; it might be removed.

The debugging code can also be switched on and off at runtime with:

    __debug (print_vars)
    {
	printf("Debug: vars = %d\n", vars);
    }
    else
    {
	printf("Release version\n");
    }
But if the -D switch is not thrown, only the else clause gets compiled.

Debug Declarations

Declarations can also be subject to the -D compiler switch:
    __debug static int x;	// compile only in debug mode
which in legacy compilers would be:
    #ifdef DEBUG
    static int x;	// compile only in debug mode
    #endif