views:

156

answers:

3

Some asserts are costly, some are better turned off at production code. At least it is not clear that assertions should be always enabled.

In my application I would like to be able to turn on/off part of assertions on per-file or per-class basis.

How to do it in C++?

A: 

To disable assertions for a C++ file, you could do one of the following:

  • Define the NDEBUG constant near the top of the source file.
  • Add the -DNDEBUG to the compilation options for the source file.

Most IDEs and/or build infrastructure allow you to specify build options per file, so this is an easy solution.

Turning off assertions on a per class basis is more difficult when multiple classes are mixed into the same source file, or you have a lot of inline functions in your header files. You can of course #define NDEBUG and #undef NDEBUG in the relevant places.

Since some IDEs expect to be able to set NDEBUG for non-debug builds, you could make it more extensible, by choosing your own macro name, such as DISABLE_ASSERT. Then include code like like the following in a common header file (that isn't precompiled):

 #ifdef DISABLE_ASSERT
 #define NDEBUG
 #endif
Stef
`#define NDEBUG` can have other undesired side-effects besides disabling asserts.
Georg Fritzsche
what side effects?
Łukasz Lew
disabling other debugging macros/code and not only asserts.
Georg Fritzsche
+1  A: 

To code with assertions considers good style of coding.

As for runtime turning on/off You may do that with Boolean variable. For example in your code you can do the following:

Define a variable which will be used to indicate if assertions are turned on or off in a global namespace (for example out of your main() function in the same file).

bool  turnOnAssertions;

Define a variable as written below in other files where you want to turn on/off your assertions:

extern bool turnOnAssertions; 

So by manipulating the turnOnAssertions variable with the UI and writing

if(turnOnAssertions)
assert(…);

you can turn on/off some of you assertions!

As for compile time you should do the following:

For you compiler you should give a flag like –DASSERTIONSON (-Dflag_name [flag name you can set anything you want])

#ifdef ASSERTIONSON 
bool turnOnAssertions = true;
#else
bool turnOnAssertions = false;
#endif

And just use the variable.

Good luck!

Narek
+2  A: 

For deactivating asserts module-wide i'd use:

#if defined(assert)
#  undef assert
#  define assert(x) ((void)0)
#endif

... of course this can be simplified if you are okay with using a custom macro.

#if defined(_NO_ASSERTS)
#  define myAssert(x) ((void)0)
#else
#  define myAssert(x) assert(x)
#endif

For class-wide deactivation i'd use a static const class member or a class-wide enum in combination with a custom macro:

#define myAssert(x) do { if(_CLASS_ASSERT) { assert(x); } } while(0)

class AssertOff
{
  enum { _CLASS_ASSERT = 0 }
}

With enums and static const bools all modern compilers should optimize away the if(_CLASS_ASSERT) {}.

Georg Fritzsche
Good idea with the enum. Thanks.
Łukasz Lew