![]() | Ned Batchelder : Blog | Code | Text | Site Asserts and implication » Home : Blog : July 2004 |
Asserts and implicationWednesday 28 July 2004 I don't know about you, but I have a hard time reading assert expressions like this: assert( id->locktype != NO_LOCK || locktype == SHARED_LOCK ); The combination of the not-equal and the logical or is difficult to parse out into an understandable condition which is being asserted as true. I encountered these today, and put my boolean algebra to use. It turns out that logical implication (a ⇒ b) is equivalent to (¬a ∨ b). The latter is just the form of expression we have in the asserts above. So these are really just if-then's compacted down into expression form. In English, they say:
Perhaps a better way to do this would be a macro for the purpose: #define IFTHEN(x, y) (!(x) || (y)) or, if you like really messing with people's heads: #define IF(x) (!(x)) Of course, you could also do the reasonable thing: if (id->locktype == NO_LOCK) { If the assert code is compiled away, the entire if statement will be also, so there's nothing lost, and much understandability is gained.
tagged:
coding» 7 reactions | |
Comments
Yes, but your way doesn't allow me to show off my l33t boolean algebra skillz.
What about if I convert...
assert(obj_is_valid(x) || x->blah == STATE_INIT);
if (!obj_is_valid(x)) assert(x->blah == STATE_INIT);
...so IMO, if you really don't like boolean algebra, you want something like assert_if();. Ie.
assert_if(!obj_is_valid(x), x->blah == STATE_INIT);
...both of which go away with NDEBUG set.
Too stiff, easily broken. Too soft, easily crashed .
Uh... do you have the same problem parsing "if" statements? It's the same thing.
if ( !pointer || pointer->thing == BLAH_BLAH )
For example.
And besides, assert statements are crap. Lead to sloppy crash handling - no chance to log an explanatory message, no chance to clean up whatever might need to be cleaned up, et cetera. Much better is something along the lines of:
if ( horrible_condition )
{
Log ( "blah blah blah, %d", horrible_condition );
exit ( EXIT_FAILURE );
}
Sorry if that doesn't indent - I think that this comment board strips leading whitespace from lines.
And I just read the paragraphs besides those on the front page, to which I say:
GOD no, don't make #defines like that. #defines for virtually any purpose besides making simple literals are a pox. And even for simple literals, consider using stuff like const shorts and enums instead of #defines.
Well, I disagree that "assert statements are crap". See my Asserts article, for example. I do agree that there is a subtle line to be drawn between asserts and explicit error checking like you propose.
And I generally agree with you that #defines can be hugely abused. Sometimes they are the lesser of two evils.
Add a comment: