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);
Related
I often find myself writing a code that looks something like this:
if(a == nullptr) throw std::runtime_error("error at " __FILE__ ":" S__LINE__);
Should I prefer handling errors with if unlikely?
if unlikely(a == nullptr) throw std::runtime_error("error at " __FILE__ ":" S__LINE__);
Will the compiler automatically deduce which part of the code should be cached or is this an actually useful thing to do? Why do I not see many people handling errors like this?
Yes you can do that. But even better is to move the throw to a separate function, and mark it with __attribute__((cold, noreturn)). This will remove the need to say unlikely() at each call site, and may improve code generation by moving the exception throwing logic entirely outside the happy path, improving instruction cache efficiency and inlining possibilities.
If you prefer to use unlikely() for semantic notation (to make the code easier to read), that's fine too, but it isn't optimal by itself.
Should I use "if unlikely" for hard crashing errors?
For cases like that I'd prefer moving code that throws to a standalone extern function that's marked as noreturn. This way, your actual code isn't "polluted" with lots of exception-related code (or whatever your "hard crashing" code). Contrary to the accepted answer, you don't need to mark it as cold, but you really need noreturn to make compiler not to try generating code to preserve registers or whatever state and essentially assume that after going there there is no way back.
For example, if you write code this way:
#include <stdexcept>
#define _STR(x) #x
#define STR(x) _STR(x)
void test(const char* a)
{
if(a == nullptr)
throw std::runtime_error("error at " __FILE__ ":" STR(__LINE__));
}
compiler will generate lots of instructions that deal with constructing and throwing this exception. You also introduce dependency on std::runtime_error. Check out how generated code will look like if you have just three checks like that in your test function:
First improvement: to move it to a standalone function:
void my_runtime_error(const char* message);
#define _STR(x) #x
#define STR(x) _STR(x)
void test(const char* a)
{
if (a == nullptr)
my_runtime_error("error at " __FILE__ ":" STR(__LINE__));
}
this way you avoid generating all that exception related code inside your function. Right away generated instructions become simpler and cleaner and reduce effect on the instructions that are generated by your actual code where you perform checks:
There is still room for improvement. Since you know that your my_runtime_error won't return you should let the compiler know about it, so that it wouldn't need to preserve registers before calling my_runtime_error:
#if defined(_MSC_VER)
#define NORETURN __declspec(noreturn)
#else
#define NORETURN __attribute__((__noreturn__))
#endif
void NORETURN my_runtime_error(const char* message);
...
When you use it multiple times in your code you can see that generated code is much smaller and reduces effect on instructions that are generated by your actual code:
As you can see, this way compiler doesn't need to preserve registers before calling your my_runtime_error.
I would also suggest against concatenating error strings with __FILE__ and __LINE__ into monolithic error message strings. Pass them as standalone parameters and simply make a macro that passes them along!
void NORETURN my_runtime_error(const char* message, const char* file, int line);
#define MY_ERROR(msg) my_runtime_error(msg, __FILE__, __LINE__)
void test(const char* a)
{
if (a == nullptr)
MY_ERROR("error");
if (a[0] == 'a')
MY_ERROR("first letter is 'a'");
if (a[0] == 'b')
MY_ERROR("first letter is 'b'");
}
It may seem like there is more code generated per each my_runtime_error call (2 more instructions in case of x64 build), but the total size is actually smaller, as the saved size on constant strings is way larger than the extra code size.
Also, note that these code examples are good for showing benefit of making your "hard crashing" function an extern. Need for noreturn becomes more obvious in real code, for example:
#include <math.h>
#if defined(_MSC_VER)
#define NORETURN __declspec(noreturn)
#else
#define NORETURN __attribute__((noreturn))
#endif
void NORETURN my_runtime_error(const char* message, const char* file, int line);
#define MY_ERROR(msg) my_runtime_error(msg, __FILE__, __LINE__)
double test(double x)
{
int i = floor(x);
if (i < 10)
MY_ERROR("error!");
return 1.0*sqrt(i);
}
Generated assembly:
Try to remove NORETURN, or change __attribute__((noreturn)) to __attribute__((cold)) and you'll see completely different generated assembly!
As a last point (which is obvious IMO and was omitted). You need to define your
my_runtime_error function in some cpp file. Since it's going to be one copy only, you can put whatever code you want in this function.
void NORETURN my_runtime_error(const char* message, const char* file, int line)
{
// you can log the message over network,
// save it to a file and finally you can throw it an error:
std::string msg = message;
msg += " at ";
msg += file;
msg += ":";
msg += std::to_string(line);
throw std::runtime_error(msg);
}
One more point: clang actually recognizes that this type of function would benefit from noreturn and warns about it if -Wmissing-noreturn warning was enabled:
warning: function 'my_runtime_error' could be declared with attribute
'noreturn' [-Wmissing-noreturn] { ^
It depends.
First of all, you can definitely do this, and this will likely (pun intended) not harm the performance of your application. But please note that likely/unlikely attributes are compiler-specific, and should be decorated accordingly.
Secondly, if you want a performance gain, the outcome will depend on the target platform (and corresponding compiler backend). If we're talking about the 'default' x86 architecture, you will not get much of a profit on modern chips - the only change these attributes will produce is a change in the code layout (unlike earlier times when x86 supported software branch prediction). For small branches (like your example), it will have very little effect on cache utilization and/or front-end latencies.
UPDATE:
Will the compiler automatically deduce which part of the code should be cached or is this an actually useful thing to do?
This is actually a very wide and complicated topic. What will compiler do depends on the particular compiler, its backend (target architecture) and compilation options. Again, for x86, here's the following rule (taken from IntelĀ® 64 and IA-32 Architectures Optimization Reference Manual):
Assembly/Compiler Coding Rule 3. (M impact, H generality) Arrange code to be consistent with
the static branch prediction algorithm: make the fall-through code following a conditional branch be the
likely target for a branch with a forward target, and make the fall-through code following a conditional
branch be the unlikely target for a branch with a backward target.
As far as I'm aware, that's the only thing that's left from static branch prediction in modern x86, and likely/unlikely attributes might only be used to "overwrite" this default behaviour.
Since you're "crashing hard" anyways, I'd go with
#include <cassert>
...
assert(a != nullptr);
This is compiler-independent, should give you close to optimal performance, gives you a breakpoint when running in a debugger, generates a core dump when not in a debugger, and can be disabled by setting the NDEBUG preprocessor symbol, which many build systems do by default for release builds.
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.
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.
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.
Take a look at this code:
#include <cassert>
#ifdef DEBUG
#define ASSERT(expr) assert(expr)
#else
#define ASSERT(expr)
#endif /* DEBUG */
The program will run only if I have DEBUG defined, otherwise it will hang and terminate with no results. I am using MinGW in Eclipse Indigo CDT. Advice is appreciated!
It's hard to tell without looking at the actual code that is causing the issue. My guess: you are evaluating an expression with side-effects within an ASSERT(). For instance, ASSERT( ++i < someotherthing ) whithin a loop. You could confirm by temporary modifying the macro definition to just expr on NDEBUG builds. After confirming this is the cause, go to each and every ASSERT call you are issuing to ensure that the expressions are side-effects free.
You are almost certainly abusing assertions. An assertion expression must never have side effects.
When you say, assert(initialize_critical_space_technology());, and then you omit this entire line in the release build, you can imagine for yourself what will happen.
The only safe and sane way to use assertions is on values:
const bool space_init = initialize_critical_space_technology();
assert(space_init);
Some people introduce a VERIFY macro for something that always executes the code:
#define VERIFY(x) (x) // release
#define VERIFY(x) (assert(x)) // debug