I have a question. In one of my projects i am using the FLAG PRINT to enable/disable the debug printfs. currently I am using something like this.
#ifdef PRINT
printf("DEBUG");
#endif
It is a pain to put this #ifdef before every printf. So I was thinking to 've a #define for the #ifdef, something like
#define DEBUG_PRINT
#define PRINT (#ifdef DEBUG_PRINT)
#define ENDPRINT #endif
so that I can use like
PRINT
printf("DEBUG");
ENDPRINT
but it is giving a compiler error. Can you tell me someway to simplify.
Thanks,
A standard way is
#ifdef DEBUG_PRINT
# define is_debug() (1)
#else
# define is_debug() (0)
#endif
#define pr_dbg(fmt, ...) do { \
if (is_debug()) \
printf(fmt, __VA_ARGS__); \
} while (0)
When using gcc, you can/should write
printf(fmt, ## __VA_ARGS__);
to deal with empty args.
In your code you can write then
pr_dbg("foo=%u\n", foo);
Optimizer will throw away the expression when DEBUG_PRINT
is not defined but your debug statements will be still checked for syntax errors. This avoids silent breakage when eg undefined variables are used within an #ifdef
clause.
How about a header with
#ifdef DEBUG
#define ON_DEBUG(X,...) do { X, __VA_ARGS__; } while( false )
#else
#define ON_DEBUG(X,...) do {} while( false )
#endif
and in your code, you simply use
ON_DEBUG( printf("Hallo, %s", "Welt") );
(the do
- while
forces you to add the final semicolon and protects the statement's in cases if (nested) if
-statements, see Aaron McDaid's comment)
I would actually do it a different way entirely. First define the flag that turns printing on or off:
// uncomment to turn off debug printing
#define DEBUG_PRINT 1
Then conditionally define your printer macro depending of the definition state of DEBUG_PRINT
:
#ifdef DEBUG_PRINT
#define PRINT (X) (printf(x))
#else
#define PRINT (x)
#endif
Which can be used simply as:
PRINT("foo");
But in reality, I wouldn't do any of this stuff at all. Instead, I'd have the turn-on/turn-off flag as above, and then build a class that does the printing:
// comment out to not do debug printing
//#define DEBUG_PRINTING 1
#ifdef DEBUG_PRINTING
class Printer
{
public:
Printer() {}
~Printer()
{
std::cout << mOutput.str() << "\n";
}
template <typename TYPE> Printer& operator<< (const TYPE& val)
{
mOutput << val;
return * this;
}
template <size_t N> Printer& operator<< (const char(&ary)[N])
{
mOutput << ary;
return * this;
}
private:
std::stringstream mOutput;
};
#else
class Printer
{
public:
Printer() {};
template <typename TYPE> Printer& operator<< (const TYPE& val)
{
return * this;
}
template <size_t N> Printer& operator<< (const char(&ary)[N])
{
return * this;
}
};
#endif
int main()
{
Printer() << "My output here. " << 42;
}
In optimized builds where the flag is not defined, most (if not all) of the code will be optimized away.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.