|
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 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 Virtual Memory For 640Kb DOS C/C++ Extensions Contract Programming __debug statement __debug declaration Dynamic Profiling Embedding C in HTML Porting to DMC++ Switching to DMC++ from Microsoft from Borland Porting Guide |
__debug StatementTwo 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 ... #endifbut 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 DeclarationsDeclarations 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
|