Based on advice in http://cnicholson.net/2009/02/stupid-c-tricks-adventures-in-assert/ I've been working with my own version of assert (called emp_assert
) for a while now. As such, when NDEBUG is set, my assert looks like:
#define emp_assert(EXPR) ((void) sizeof(EXPR) )
This definition assures that any variables in EXPR still count as "used" in the compiler, but do not affect run-time performance.
Unfortunately, I've recently discovered that any use of lambdas within an assert produce a compilation error since lambdas cannot be put into a sizeof.
My options seem to be:
- Simply remove the sizeof; I have very few cases in my code with otherwise unused variables and can just deal with them manually.
- Avoid using labdas within asserts.
- Come up with a replacement for sizeof that would have the same effect.
Option 1 is currently my top choice, but I use this assert system with many projects and would likely stumble on problems for some time to come.
Option 2 seems too limiting, especially since I can imagine unexpected interactions in the future.
Option 3 would be the most elegant, drop-in solution, but I could use help coming up with an idea for how to accomplish it.
EDIT: Here is some example code to illustrate the problem.
#include <iostream>
#include <algorithm>
#include <vector>
#define NDEBUG
// Relevant excerpt from "emp_assert.h"
#ifdef NDEBUG
#define emp_assert(EXPR) ((void) sizeof(EXPR))
#else
#define emp_assert(EXPR) \
do { if ( !(EXPR) ) { \
std::cerr << "Assert Error (In " << __FILE__ \
<< " line " << __LINE__ \
<< "): " << #EXPR << std::endl; \
abort(); } \
} while (0)
#endif
// Code to trigger the problem (asserting that all ints in a vector are less than 8.)
int main()
{
std::vector<int> v = {1, 2, 3, 4, 8};
emp_assert( std::all_of(v.begin(), v.end(), [](int i){return i < 8;}) );
}
Comment out the #define NDEBUG
to see how the code will compile correctly and trip the assert when run. (Remove the 8 from the vector if you don't want the assert to trip).
I compiled using g++ -std=c++11 file.cc