I would have assumed this would be a widely asked question, but still I have yet to find an answer.
I was debugging some C++ code that was creating errors in a subtle way only with certain function handles as inputs. Long story short fixed the problem but I defined in the .cpp file:
#define DEBUG(x) do { std::cerr << x << std::endl; } while (0)
needless to say the code is littered with:
DEBUG("Foo's address")
DEBUG(&Foo)
Now I assumed that in "Release" that the compiler would ignore all these pre-compiler outputs. But it doesn't!
So how does one do this in practice (I want to leave the outputs for future additions, but obviously don't want it in release versions)? I'm trying out clion which uses cmake, is this something IDE/compiler specific?
Thanks
Depending on your compiler it may define something that tells you that compilation is in debug mode (or you can do that yourself on the command line), then:
#ifndef _DEBUG // works in VS
#define DEBUG(x)
#else
#define DEBUG(x) do { std::cerr << x << std::endl; } while (0)
#endif
For more discussion on which macro to use, see this question.
Portable way of doing this would be using NDEBUG
#ifdef NDEBUG
#define DEBUG(x)
#else
#define DEBUG(x) do { std::cerr << x << std::endl; } while (0)
#endif
See: C / C++ : Portable way to detect debug / release?
It is usually a mistake to eliminate logging messages in so-called "release versions". After all, "release versions" are where you will need the logged information most! How else will you even hope to analyse and fix the problem when the end user will tell you nothing but "it doesn't work" or "it crashed"?
So instead of eliminating the valuable information that your software creates to aid you in your bugfixing sessions, think about how to save and persist it such that it can be easily transmitted to you by the end user if problems arise. Like, redirecting the log messages to a log file when the application runs on the user's machine (perhaps with the application itself offering a "Send log file to support" feature, or something like that).
Code like
DEBUG("Foo's address")
DEBUG(&Foo)
should be replaced with something like:
Log("Foo's address");
Log(std::to_string(&Foo));
Then inside of your Log function, which may have a signature like void Log(std::string const& message), you can check your DEBUG macro and act accordingly:
void Log(std::string const& message)
{
#ifdef DEBUG
// write message to std::cerr
#else
// write message to log file
#endif
}
Now, of course, DEBUG is not a standard macro (unlike NDEBUG, which turns assert on and off). It's not implicitly defined. You have to define it yourself when you invoke your compiler. For example, /DDEBUG with MSVC or -DDEBUG with GCC. Chances are that your IDE adds such a flag, or something similar like -D_DEBUG when it runs the compiler, but still, that's not standard and not part of the compiler itself. (Actually, you might consider a different name for the macro anyway if you are going to use it like this, something like LOG_TO_CONSOLE.)
In any case, this is just to give you an inspiration of what do do. You may prefer a std::ostream-based approach instead of a function taking a std::string. There are a lot of questions and answers on Stackoverflow about this.
The important point is: Don't throw away valuable log information under the assumption that you won't need it once your software is released. There will be bugs and vague error descriptions.
Related
I would like to be able to do something like this using visual c++ compiler (vc12):
// If we have compiled with O2
#ifdef _O2_FLAG_
bool debug_mode = false;
// If we are in dirty slow non optimized land
#else
bool debug_mode = true;
#endif
But I cannot find a predefined macro for this purpose.
Context:
The debug_mode flag is used like:
if (!debug_mode && search_timer->seconds_elapsed() > 20) {
return best_result_so_far;
}
The problem being that in a debug instance that I step through this constantly fails and bombs me out because strangely it takes me a lot longer to step through the code than the CPU normally goes through it :-)
If there is some underlying clock that pauses when debug does that would also solve my problem. Currently I am using the difference between two calls to std::chrono::high_res_clock::now().
EDIT:
In response to several comments explaining why I don't want to do what I want to do, I should perhaps reword the question as simply: Is there an equivalent of gcc's __optimize__ in cl?
You could use either _DEBUG or NDEBUG to detect the debug configuration. This technically doesn't mean the same thing as the optimization flag, but 99% of the time this should suffice.
Another option would be to add a preprocessor definition to the project yourself.
Is there a "best practice" or similar for coding in a debug-mode in one's code?
For example,
#include <iostream>
int main()
{
#ifdef MY_DEBUG_DEF
std::cout << "This is only printed if MY_DEBUG_DEF is defined\n";
#endif
return 0;
}
Or is this considered bad practice because the code gets bit messier?
I have noticed some libraries (for example libcurl, which is a large and well-known library) have this feature; if you define VERBOSE with libcurl you get basically a debug mode
Thank you.
A more usual way is to follow conventions from assert(3): wrap with #ifndef NDEBUG .... #endifcode which is only useful for debugging, and without any significant side effects.
You could even add some debug-printing macro like
extern bool wantdebug;
#ifndef NDEBUG
#define OUTDEBUG(Out) do { if (wantdebug) \
std::cerr << __FILE__ << ":" << __LINE__ \
<< " " << Out << std::endl; \
} while(0)
#else
#define OUTDEBUG(Out) do {}while(0)
#endif
and use something like OUTDEBUG("x=" << x) at appropriate places in your code. Then wantdebug flag would be set thru the debugger, or thru some program arguments. You probably want to emit a newline and flush cerr (or cout, or your own debug output stream) -using std::endl ...- to get the debug output displayed immediately (so a future crash of your program would still give sensible debug outputs).
That is an acceptable method. Yes, it gets messy, but it makes it a lot easier to debug as well. Plus you can normally collapse those kinds of things, thus removing the messiness.
As you've mentioned, libcurl uses the method. I also used to have a teacher who works for HP on their printer software, and they used the same method.
I personally prefer runtime enabled logging. That means that you don't have to recompile to get the "debug output". So I have a command-line argument -v=n, where n defaults to zero, and gets stored in the variable verbosity in the actual program. With -v=1 I get basic tracing (basic flow of the code), with -v=2 I get "more stuff" (such as dumps of internal state in selected functions). Two levels is often enough, but three levels may be good at times. An alternative is to make verbosity a bit-pattern, and enable/disable certain functionality based on which bits are set - so set bit 0 for basic trace, bit 1 gives extra info in some module, bit 2 gives extra trace in another module, etc. If you want to be REALLY fancy, you have names, such as -trace=all_basic, -trace=detailed, -trace=module_A, -trace=all_basic,module_A,module_B or some such.
Combine this with a macro along the lines of:
#define TRACE do { if (verbosity > 0) \
std::cout << __FILE__ << ":" << __LINE__ << ":" \
<< __PRETTY_FUNCTION__ << std::endl; } while(0)
For things that may take a substantial amount of extra time, such as verifying the correctness of a large and complex data structure (tree, linked list, etc), then using #ifndef NDEBUG around that code would be a good thing. Assuming of course you believe that you'll never mess that up in a release build.
Real livig code here:
https://github.com/Leporacanthicus/lacsap/blob/master/trace.h
https://github.com/Leporacanthicus/lacsap/blob/master/trace.cpp
being use here for example:
https://github.com/Leporacanthicus/lacsap/blob/master/expr.cpp
(Note that some simple functions that get called a lot don't have "TRACE" - it just clutters up the trace and makes it far too long)
Using logger may be better, e.g.
log4cxx
log4cpp
ACE_Log_Msg: It is in ACE
Boost.Log:
The above are very flexible, but heavyweight. You can also implement some simple macros instead:
#ifdef NDEBUG
#define DBG(FMT, ...)
#else // !NDEBUG
#define DBG(FMT, ...) fprintf (stderr, FMT, ## __VA_ARGS__)
#endif // NDEBUG
The above is GCC syntax from Macros with a Variable Number of Arguments.
For VC, please see also How to make a variadic macro (variable number of arguments)
I want to realize this behavior:
When program runs in debug mode, assert_robust(expression, commands) works strictly like classical assert(expression)
When program runs in release mode, assert_robust(expression, commands) perform some commands if expression is false
This can be done this way:
#ifdef NDEBUG
#define assert_robust(expression, command) if (!(expression)) command;
#else
#define assert_robust(expression, command) assert(expression);
#endif
And this can be used for example this way to make myfunction fault-tolerant:
char myfunction(const string& s, int i)
{
assert_robust(i >= 0, return '\0');
/* Normal code */
}
This work well, but how to make macro assert_robust that supports more than one (arbitrary) number of commands? (preferably by a standard C++ way)
And another question is:
Is it good thing to be strict in debug and benevolent in release?
EDIT: My idea why do such a thing is because it is practicaly much better if it is a bug in the program that the program maintains sometimes a little weird than when it crashes and user losing their data.
The more interesting question is the second:
Is it good thing to be strict in debug and benevolent in release?
My experiences is that it is a horrible idea to have different behavior in debug and release builds. You are signing up for issues in production that you will never be able to reproduce in a debug build because the behavior of the two is different.
Other than that, which you may claim won't be an issue if you assert in the first place in debug mode, asserts should be used to flag programming issues, situations from which you cannot recover safely. If you can recover safely in release mode, why assert in DEBUG? If you cannot, are you willing to fiddle with production data in a way you don't quite understand what it will do?
Without getting into the issue of if this is a good idea or not, you can use your macro to wrap multiple commands in a do-while(0); loop.
#ifdef NDEBUG
#define assert_robust(expression, command) if (!(expression)) \
do{command;} while(0)
#else
#define assert_robust(expression, command) assert(expression)
#endif
Note also that I did not include semicolons at the ends of the macros. If you include them in the macros, then something like
assert_robust(cond1, command1) /* no semicolon here, no problem */
assert_robust(cond2, command2) /* no semicolon here, no problem */
would be allowed, which would be really weird.
I don't think to use assertions this way is a good idea. Usually you use an assert, if you want the predicate to be always true, because its part of critical code. If its not true, than there is obviously a big problem and aborting is reasonable. But more and more people use assert like an ordinary error check for debugging. In this case its adequate to disable it completely in release mode. It think you should decide for one of this two approaches.
But if you want to run some kind of emergency commands before aborting, you could use the new lambda functions from C++11:
void ASSERT(int expression, std::function<void()> func) {
if(!expression) {
if (func) func();
abort();
}
}
You could use it like this:
ASSERT(a >= 0, []() { std::cerr << "ERROR" << std::endl;});
Or:
ASSERT(a >= 0, [this]() { this->terminate(); });
Or:
ASSERT(a >= 0, nullptr);
I'd like to have the possibility to increase the verbosity for debug purposes of my program. Of course I can do that using a switch/flag during runtime. But that can be very inefficient, due to all the 'if' statements I should add to my code.
So, I'd like to add a flag to be used during compilation in order to include optional, usually slow debug operations in my code, without affecting the performance/size of my program when not needed. here's an example:
/* code */
#ifdef _DEBUG_
/* do debug operations here
#endif
so, compiling with -D_DEBUG_ should do the trick. without it, that part won't be included in my program.
Another option (at least for i/o operations) would be to define at least an i/o function, like
#ifdef _DEBUG_
#define LOG(x) std::clog << x << std::endl;
#else
#define LOG(x)
#endif
However, I strongly suspect this probably isn't the cleanest way to do that. So, what would you do instead?
I prefer to use #ifdef with real functions so that the function has an empty body if _DEBUG_ is not defined:
void log(std::string x)
{
#ifdef _DEBUG_
std::cout << x << std::endl;
#endif
}
There are three big reasons for this preference:
When _DEBUG_ is not defined, the function definition is empty and any modern compiler will completely optimize out any call to that function (the definition should be visible inside that translation unit, of course).
The #ifdef guard only has to be applied to a small localized area of code, rather than every time you call log.
You do not need to use lots of macros, avoiding pollution of your code.
You can use macros to change implementation of the function (Like in sftrabbit's solution). That way, no empty places will be left in your code, and the compiler will optimize the "empty" calls away.
You can also use two distinct files for the debug and release implementation, and let your IDE/build script choose the appropriate one; this involves no #defines at all. Just remember the DRY rule and make the clean code reusable in debug scenario.
I would say that his actually is very dependent on the actual problem you are facing. Some problems will benefit more of the second solution, whilst the simple code might be better with simple defines.
Both snippets that you describe are correct ways of using conditional compilation to enable or disable the debugging through a compile-time switch. However, your assertion that checking the debug flags at runtime "can be very inefficient, due to all the 'if' statements I should add to my code" is mostly incorrect: in most practical cases a runtime check does not influence the speed of your program in a detectable way, so if keeping the runtime flag offers you potential advantages (e.g. turning the debugging on to diagnose a problem in production without recompiling) you should go for a run-time flag instead.
For the additional checks, I would rely on the assert (see the assert.h) which does exactly what you need: check when you compile in debug, no check when compiled for the release.
For the verbosity, a more C++ version of what you propose would use a simple Logger class with a boolean as template parameter. But the macro is fine as well if kept within the Logger class.
For commercial software, having SOME debug output that is available at runtime on customer sites is usually a valuable thing to have. I'm not saying everything has to be compiled into the final binary, but it's not at all unusual that customers do things to your code that you don't expect [or that causes the code to behave in ways that you don't expect]. Being able to tell the customer "Well, if you run myprog -v 2 -l logfile.txt and do you usual thing, then email me logfile.txt" is a very, very useful thing to have.
As long as the "if-statement to decide if we log or not" is not in the deepest, darkest jungle in peru, eh, I mean in the deepest nesting levels of your tight, performance critical loop, then it's rarely a problem to leave it in.
So, I personally tend to go for the "always there, not always enabled" approach. THat's not to say that I don't find myself adding some extra logging in the middle of my tight loops sometimes - only to remove it later on when the bug is fixed.
You can avoid the function-like macro when doing conditional compilation. Just define a regular or template function to do the logging and call it inside the:
#ifdef _DEBUG_
/* ... */
#endif
part of the code.
At least in the *Nix universe, the default define for this kind of thing is NDEBUG (read no-debug). If it is defined, your code should skip the debug code. I.e. you would do something like this:
#ifdef NDEBUG
inline void log(...) {}
#else
inline void log(...) { .... }
#endif
An example piece of code I use in my projects. This way, you can use variable argument list and if DEBUG flag is not set, related code is cleared out:
#ifdef DEBUG
#define PR_DEBUG(fmt, ...) \
PR_DEBUG(fmt, ...) printf("[DBG] %s: " fmt, __func__, ## __VA_ARGS__)
#else
#define PR_DEBUG(fmt, ...)
#endif
Usage:
#define DEBUG
<..>
ret = do_smth();
PR_DEBUG("some kind of code returned %d", ret);
Output:
[DBG] some_func: some kind of code returned 0
of course, printf() may be replaced by any output function you use. Furthermore, it can be easily modified so additional information, as for example time stamp, is automatically appended.
For me it depends from application to application.
I've had applications where I wanted to always log (for example, we had an application where in case of errors, clients would take all the logs of the application and send them to us for diagnostics). In such a case, the logging API should probably be based on functions (i.e. not macros) and always defined.
In cases when logging is not always necessary or you need to be able to completely disable it for performance/other reasons, you can define logging macros.
In that case I prefer a single-line macro like this:
#ifdef NDEBUG
#define LOGSTREAM /##/
#else
#define LOGSTREAM std::clog
// or
// #define LOGSTREAM std::ofstream("output.log", std::ios::out|std::ios::app)
#endif
client code:
LOG << "Initializing chipmunk feeding module ...\n";
//...
LOG << "Shutting down chipmunk feeding module ...\n";
It's just like any other feature.
My assumptions:
No global variables
System designed to interfaces
For whatever you want verbose output, create two implementations, one quiet, one verbose.
At application initialisation, choose the implementation you want.
It could be a logger, or a widget, or a memory manager, for example.
Obviously you don't want to duplicate code, so extract the minimum variation you want. If you know what the strategy pattern is, or the decorator pattern, these are the right direction. Follow the open closed principle.
I have the following code snippet:
#ifdef DO_LOG
#define log(p) record(p)
#else
#define log(p)
#endif
void record(char *data){
.....
.....
}
Now if I call log("hello world") in my code and DO_LOG isn't defined, will the line be compiled, in other words will it eat up the memory for the string "hello world"?
P.S. There are a lot of record calls in the program and it is memory sensitive, so is there any other way to conditionally compile so that it only depends on the #define DO_LOG?
This should be trivial to verify for yourself by inspecting the resulting binary.
I would say "no", since the expression totally goes away, the compiler will never see the string (it's removed by the preprocessor's macro expansion).
Since the preprocessor runs before the compiler, the line will not even exist when the compiler runs. So the answer is no, it does not use any memory at all.
No, it will not be in the binary. It will not even be compiled - the preprocessor will expand it into an empty string prior to the compilation, so the compiler will not even see it.
No. The preprocessor is executed prior to compilation, and so the code will never even be seen. I would like to add, though, that if you are interested in adding logging to your C++ application, you might want to use the Log4Cxx library. It uses similar macros which you can completely elide from your application, but when logging is enabled, it supports several different levels of logging (based on importance/severity) as well as multiple different "appenders" to which to send logging output (e.g. syslog, console, files, network I/O, etc.).
The full API documentation may be found at Log4Cxx API docs. Also, if you have any Java developers on board who have used Log4J, they should feel right at home with Log4Cxx (and convince you to use it).