On Thu, 9 Feb 2012, Kim Barrett wrote:
On Feb 9, 2012, at 1:47 AM, John M. Dlugosz wrote:
On 2/9/2012 12:21 AM, Jeremiah Willcock wrote:
Would it be reasonable for your use case to have MY_FANCY_ASSERT be:
#define MY_FANCY_ASSERT(cond, str) \ if (cond) {} else format(str) % __FILE__ % __LINE__
or similar? It would restrict where you could use it, but would be simple and guarantee the properties you want.
Actually, that's not at all too unreasonable. I had shied away from making a macro that "eats" the following arguments in a non-expression way, on general principles. But I see that what you have doesn't leave a dangling-else problem, and I suppose people won't notice that it's at all funny.
I have a similar macro and just yesterday received a bug report from one of my users because code like this
if (cond1) MY_FANCY_ASSERT(cond2, ...) ... ;
was resulting in compiler warnings from gcc: -Wparentheses (enabled by -Wall) complains about potential confusion over which "if" an "else" belongs to. I was unable to find a way to suppress the warning locally to the macro, even with the local diagnostic control pragmas available in gcc4.6 (though it might be argued that some of what I was seeing should be considered gcc bugs (I intend to file a bug report), so it might be that some future version of gcc will provide sufficient warning control for this situation). The workarounds are, of course, to move cond1 into the macro's conditional or to put braces around the whole outer "then" statement.
Here's a variant that might work better for that: #define MY_FANCY_ASSERT(cond, str) \ for (bool BOOST_PP_CAT(assertcond, __LINE__) = (cond); \ BOOST_PP_CAT(assertcond, __LINE__); \ BOOST_PP_CAT(assertcond, __LINE__) = false) \ format(str) % __FILE__ % __LINE__ -- Jeremiah Willcock