On Tue, Aug 9, 2011 at 1:59 PM, Chris Lattner <span dir="ltr"><<a href="mailto:clattner@apple.com">clattner@apple.com</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

<div class="im"><br>
On Aug 8, 2011, at 10:46 PM, Talin wrote:<br>
<br>
> So I went ahead and implemented this in my own frontend - I've been using it for both assertions and conditional debug statements. I like it quite a bit, and like you say, it compiles down to nothing in non-debug builds.<br>


<br>
</div>Does:<br>
   YOUR_DEBUG_MACRO(…) << some_out_of_line_function();<br>
<br>
Still evaluate the out of line function?  If so, it seems that something like the LLVM "DEBUG" macro is a better approach.<br></blockquote><div><br></div><div>No it does not. Basically the macro expands to a ternary operator:</div>

<div><br></div><div>    (expression) ? (void)0 : VoidResult & Stream</div><div><br></div><div>Because the precedence of ?: is lower than <<, all of the stream operators get associated with the stream object, rather than with the expression as a whole. And C++ guarantees that no side effects will happen for the right hand side if the expression is true. So none of the stream operators or their arguments get evaluated.</div>

<div><br></div><div>The "VoidResult" is there because both sides of a ternary operator have to be the same type, which in this case we want it to be type void. There's an overloaded operator& which takes (VoidResult, Stream) and returns a void. It's inline and does nothing. Since the precedence of & is lower than <<, we still get all of the stream operators attaching to the stream object.</div>

<div><br></div><div>However, if you think that's too magical, let me suggest something much less grandiose. Before I started using these new debug macros, my older debug macros looked like this:</div><div><br></div><div>

   DASSERT(expression);</div><div>   DASSERT_ARG(expression, arg);</div><div><br></div><div>The DASSERT_ARG macro prints "assertion failed: <expression>, context: <arg>". "arg" can be any object that is streamable to a raw_ostream. This allows me to know a little bit more information about the failure, such as which type or variable was involved.</div>

<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<font color="#888888"><br>
-Chris</font></blockquote></div><br><br clear="all"><br>-- <br>-- Talin<br>