Re: Verify and expression
* Mark Van Peteghem:
Alf P. Steinbach schreef:
* Mark Van Peteghem:
Another pitfall is that the ability to use it as an expression makes
it not so extensible. When you want to add expressions, a level, a
group and or an optional action, you need to wrap it in a if-else
construct, so it can no longer be used as expression.
Could you elaborate on this?
As far as I know this is a valid C++ statement:
42;
I didn't talk about statements, only expressions. Maybe I didn't
explain too well what I mean with adding expressions: I meant
expressions that are logged and displayed along with the other
information about a failed assertion; in ModAssert you can do that
with
MOD_ASSERT_P(a << b, a+b==10);
where a and b would be logged and displayed if the condition failed.
To be able to do that, MOD_ASSERT_P has to be defined as a if-else
construct, so it can no longer be used as an expression.
I don't understand (but then, what else is new?).
Let's say I define MOD_ASSERT_P like this -- off the cuff:
#define MOD_ASSERT_P( sideEffect, assumption ) \
((assumption)? true : (sideEffect, std::terminate(), true))
perhaps conditionally defined with a do-nothing variant for NDEBUG.
I don't know the spec for MOD_ASSERT_P, but just assume the above
definition, unless it's way too different from what the real
MOD_ASSERT_P does.
The only potential problem I can think of at the moment is that the
value of 'assumption' is used more than once but shouldn't be evaluated
more than once, for fear of side-effects. And that one of those
potential evaluations is as an argument to 'assert'. But for that there
is both the solution of global variable + stringizing, and the solution
of requiring 'assumption' to have no side effects, which I think best.
A stringizing solution to that potential problem (not using a global
variable because here there's just one evaluation in addition to assert)
-- not that I would necessarily choose this solution -- might look
like this:
inline bool trueSansWarning() { return true; }
#define BECAUSE_NOT_TRUE( e ) (void(#e), false)
#define MOD_ASSERT_P( sideEffect, assumption ) \
((assumption)? trueSansWarning() : ( \
sideEffect, \
assert( BECAUSE_NOT_TRUE(assumption) ), std::terminate(), \
trueSansWarning() \
) \
)
Admittedly, I did have to put this last example through the compiler(s),
and admittedly, for MOD_ASSERT_P the ability to serve as an expression
seems to me to be of dubious value (as opposed to e.g. a TERMINATE macro
without any assumption to be tested), but what's the problem?
Well, except for Visual C++ warning about unreachable code (one of the
countless silly-warnings that should simply be turned off), I mean?
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]