Online Book Reader

Home Category

Professional C__ - Marc Gregoire [456]

By Root 1395 0
", __VA_ARGS__)

#else

#define log(...)

#endif

class ComplicatedClass

{

public:

ComplicatedClass() {}

};

class UserCommand

{

public:

UserCommand() {}

};

ostream& operator<<(ostream& ostr, const ComplicatedClass& src);

ostream& operator<<(ostream& ostr, const UserCommand& src);

UserCommand getNextCommand(ComplicatedClass* obj);

void processUserCommand(UserCommand& cmd);

void trickyFunction(ComplicatedClass* obj) throw(exception);

int main(int argc, char* argv[])

{

#ifdef DEBUG_MODE

// Print the command-line arguments to the trace

for (int i = 0; i < argc; i++) {

log(argv[i]);

}

#endif

ComplicatedClass obj;

trickyFunction(&obj);

// Rest of the function not shown

return 0;

}

ostream& operator<<(ostream& ostr, const ComplicatedClass& src)

{

ostr << "ComplicatedClass";

return ostr;

}

ostream& operator<<(ostream& ostr, const UserCommand& src)

{

ostr << "UserCommand";

return ostr;

}

UserCommand getNextCommand(ComplicatedClass* obj)

{

UserCommand cmd;

return cmd;

}

void processUserCommand(UserCommand& cmd)

{

// details omitted for brevity

}

void trickyFunction(ComplicatedClass* obj) throw(exception)

{

log("given argument: ", *obj);

for (size_t i = 0; i < 100; ++i) {

UserCommand cmd = getNextCommand(obj);

log("retrieved cmd ", i, ": ", cmd);

try {

processUserCommand(cmd);

} catch (const exception& e) {

log("received exception from processUserCommand(): ", e.what());

throw;

}

}

}

Code snippet from CompileTimeDebugMode\CTDebug.cpp

This implementation uses the following macro:

#ifdef DEBUG_MODE

#define log(...) Logger::log(__func__, "(): ", __VA_ARGS__)

#else

#define log(...)

#endif

In debug mode, every call to log() in your code will be replaced with a call to the Logger::log() method. The macro automatically includes the function name, __func__, as first argument to the Logger::log() method.

When the DEBUG_MODE symbol is not defined, log() is defined as being empty, which will basically remove all log() calls in your code. For example, take the following line:

log("given argument: ", *obj);

If DEBUG_MODE is defined, the macro will replace this with:

Logger::log(__func__, "(): ", "given argument: ", *obj);

However, if DEBUG_MODE is not defined, the macro will replace the line with:

;

Be careful not to put any code that must be executed for correct program functioning inside your log() calls. For example, a line like this is probably asking for trouble: log("Result: ", myFunctionCall()). If DEBUG_MODE is not defined, the preprocessor will strip all log() calls, which means the call to myFunctionCall() will be stripped as well.

Macros in C++ should be avoided as much as possible because they can be hard to debug. However, for logging purposes, using a simple macro is acceptable and it makes using the logging code much easier.

Start-Time Debug Mode

Start-time debug mode is an alternative to #ifdefs that is just as simple to implement. A command-line argument to the program can specify whether it should run in debug mode. Unlike compile-time debug mode, this strategy includes the debug code in the “release” binary, and allows debug mode to be enabled at a customer site.

However, it still requires users to restart the program in order to run it in debug mode, which is not always an attractive alternative for customers, and which may prevent you from obtaining useful information about bugs.

The following example of start-time debug mode uses the same program as that shown for compile-time debug mode so that you can directly compare the differences. Changes are highlighted.

One aspect of this program needs further comment: There is no standard library functionality in C++ for parsing command-line arguments. This program uses a simple function isDebugSet() to check for the debug flag among all the command-line arguments, but a function to parse all command-line arguments would need to be more sophisticated.

class Logger

{

public:

static void enableLogging(bool enable) { msLoggingEnabled = enable; }

static bool isLoggingEnabled() { return

Return Main Page Previous Page Next Page

®Online Book Reader