Most answers suggest using the static_cast<void>(expression) trick in the Release lines to suppress the warning, but this is actually suboptimal if you intend to do validation checks really Debug - only. The objectives of the approval macro are:
- Perform
Debug Checks - Do nothing in
Release mode - Do not issue warnings in all cases
The problem is that the void-cast method does not reach the second goal. Although there is no warning, the expression you passed to the approval macro will still be evaluated. If you, for example, just do a variable check, this probably doesn't matter much. But what if you call some function in your statement validation, for example, ASSERT(fetchSomeData() == data); (which is very common in my experience)? The fetchSomeData() function will still be called. It may be quick and easy, or it may not.
What you really need is not only a warning, but, perhaps more importantly, not an evaluation of the validation expression, only debugging. This can be achieved with a simple trick, which I took from the Assert specialized library:
void myAssertion(bool checkSuccessful) { if (!checkSuccessful) { // debug break, log or what not } }
All magic is in the DONT_EVALUATE macro. Obviously, at least logically, evaluating your expression is never needed inside it. To reinforce this, the C ++ standard ensures that only one of the branches of the conditional statement will be evaluated. Here is a quote:
5.16 Conditional operator [expr.cond]
boolean or expression? expression: assignment-expression
Group conditional expressions from right to left. The first expression is contextually converted to bool. It is evaluated, and if so, the result of the conditional expression is the value of the second expression, in contrast to the third expression. Only one of these expressions is evaluated.
I tested this approach in GCC 4.9.0, clang 3.8.0, VS2013 Update 4, VS2015 Update 4 with the most stringent warning levels. In all cases, there are no warnings, and the validation expression is never evaluated in the Release build (in fact, all this is fully optimized). Do not forget that with this approach you will quickly run into trouble if you place expressions that have side effects inside the statement macro, although this is, first of all, a very bad practice.
In addition, I would expect static analyzers to warn that "the result of an expression is always constant" (or something similar) with this approach. I tested this with the clang, VS2013, VS2015 static analysis tools and did not receive any warnings of this kind.