Re: Verify and expression
alfps@start.no (Alf P. Steinbach) wrote (abridged):
Featurism! ;-)
As I said, it's something I picked up from another post, not something I
added myself.
Anyway, the above is very possible, but I'd prefer
char const* s = strdup( "test" );
!!s || TERMINATE( "out of memory" );
The benefit is more in situations where there is no named variable. For
example:
return VERIFY( strdup( "test" ), "out of memory" );
if (some_condition)
some_function( VERIFY( strdup( "test" ), "out of memory" ) );
In the second example, adding a variable would turn one line into three
lines plus braces - potentially 5 lines depending on layout. As Andrei
says, vertical space is precious.
There may be an element of psychology involved, too. In my experience,
some programmers are reluctant to use assertions at all, so we need to
make it as unintrusive and transparent as we can. That's part of why
preserving the expression's type and value matter.
(You mention also using a global variable to store the condition's
value, but I think that suffers from not being re-entrant or
thread-safe.
[...]
In short, the argument seems to be, "because C++ does not currently
support threading, nothing can be implemented in C++ (it would not be
thread safe)", which smacks of fallacy, at least to my tongue's taste
buds.
Did you miss the word "re-entrant"? I had in mind code like:
return VERIFY( p->value(), p->name() << " has bad value" );
where p->name() may itself use VERIFY. Global variables are problematic
even without multi-threading.
In any case, even if you don't use threads, they are part of the modern
C++ landscape for many of us. The original poster wanted to know if there
were any pitfalls in the approach he was taking. In that context it is
certainly worth mentioning threading issues.
Please elaborate -- a specific, clear example would be nice
How about:
return VERIFY( p->value(), "bad value from: " << p->dump() );
where:
(a) p->value() should be evaluated exactly once regardless of
whether checks are enabled.
(b) The type and value returned should be the same as the type and
value of p->value(). (You can return 0 on failure, but it'd be
even better if that wasn't necessary.)
(c) p->value() may also use VERIFY.
(d) p->dump() may also use VERIFY.
(e) The code should be thread-safe.
(f) p->dump() is evaluated only if the check fails.
That's listed in my personal order of importance. (f) is the one I would
drop. The ideal VERIFY would satisfy them all.
-- Dave Harris, Nottingham, UK.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]