www.digitalmars.com Home | Search | CTG | RTL | IDDE | STL
Last update Sun Apr 9 00:16:31 2006
Compiler & Tools Guide

Compiling
Compiling Code
C Implementation
C++ Implementation
Language Extensions
Mixing Languages
Assembly Language
Inline Assembler
Optimizing Code
Numerics Programming
Regular Expressions
Acrtused
Pragmas
Precompiled Headers
Predefined Macros
Warning Messages
Error Messages
Runtime Messages


Linking
Optlink
Switches
Module Definition Files
Operation and Design
Error Messages


Win32 Programming
Win32 Programming


DOS and Win16
Programming

Memory Models
16 Bit Pointer Types
and Type Modifiers

Handle Pointers
DOS
DOS 32 (DOSX)
Win16
Win16 DLLs
Win16 Prolog/Epilog


C/C++ Extensions
Contract Programming
__debug statement
__debug declaration
Dynamic Profiling
Embedding C in HTML


Tools
BCC
CHMOD
CL
COFF2OMF
COFFIMPLIB
DMC
DIFF
DIFFDIR
DUMP
DUMPOBJ
DUMPEXE
EXE2BIN
FLPYIMG
GREP
HC
IMPLIB
LIB
LIBUNRES
MAKE
MAKEDEP
ME
OBJ2ASM
PATCHOBJ
RC
RCC
SC
SHELL
SMAKE
TOUCH
UNMANGLE
WHEREIS


Porting to DMC++
Switching to DMC++
from Microsoft
from Borland
Porting Guide


__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