When working on a large legacy code base, I today suspected a duplicate definition, but the dependency was not obvious to me human since it depended on a lots of compile-time calculations.
enum { MAX_ITEMS = 4 }; // defined somewhere in my code universe
enum { ITEMS_MAX = COMPLICATED_CALCULATIONS }; // somewhere else
I remembered some cases with analogous sizeof
questions, when I let the compiler speak.
I usually put some ad-hoc formulations like this in the code (in the IDE), then I press [Alt]+[F9]:
void check() {
char bla[MAX_ITEMS == ITEMS_MAX]; // compiler-error shows difference
// ...but it causes a compiler warning about bla being never used
}
...and that's only because my compiler (Borland C++ 5.6.4) lazy evaluates the typedef
for arrays with non-literal dimension:
typedef char bla[0]; // immediate compiler error
typedef char bla[0 != 0]; // obvious, but no compiler error HERE
Is there a really easy-to-memorize way for checks like this? And, please don't blame an old brave compiler ;-)
This works:
#define STATIC_ASSERT(x) typedef char foo[(x) ? 1 : -1];
I actually use the following setup borrowed from Boost, the purpose of this is to give each foo its own line number (otherwise a multiple definition error can happen):
#define BOOST_JOIN( X, Y ) BOOST_DO_JOIN( X, Y )
#define BOOST_DO_JOIN( X, Y ) BOOST_DO_JOIN2(X,Y)
#define BOOST_DO_JOIN2( X, Y ) X##Y
#define STATIC_ASSERT(x) \
typedef char BOOST_JOIN(violation_on_line_,__LINE__) [(x) ? 1 : -1];