<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Jul 27, 2011, at 12:51 AM, Chandler Carruth wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div class="gmail_quote">On Tue, Jul 26, 2011 at 10:41 AM, Talin <span dir="ltr"><<a href="mailto:viridia@gmail.com">viridia@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div id=":jh2">The assertions in LLVM would be a lot more useful if they could print out not only the source code of the expression that failed, but also print the values of the various arguments. To that end, I have an idea for an improved assert macro which would use raw_ostream. It would look something like this:<div>
<br></div><div><font face="'courier new', monospace"> ASSERT_STRM(Ty == STy, "Expected " << Ty << " but got " << STy->getElementType(0));</font></div></div></blockquote>
</div><br><div>Chromium (and several other Google open source projects) have a somewhat superior variant of this:</div><div><br></div><div><a href="http://google.com/codesearch#hfE6470xZHk/base/logging.h&exact_package=http://src.chromium.org/git/chromium.git&q=CHECK&type=cs&l=398">http://google.com/codesearch#hfE6470xZHk/base/logging.h&exact_package=http://src.chromium.org/git/chromium.git&q=CHECK&type=cs&l=398</a></div>
<div><br></div><div>It ends up looking like:</div><div><br></div><div>CHECK(Ty == STy) << "Expected " << Ty << " .." << ...;</div><div><br></div><div>The important difference is that most of the parameters go outside of the macro rather than inside, making error messages way more intelligible. *If* we want to go this direction in LLVM, I'd much rather see this formulation. It's still easy to have it compile away to nothing using ?: operator.</div>
<div><br></div><div>*If* there is a desire to go this route, I've worked closely with several variants of the pattern and would be happy to contribute a minimal implementation.</div><div><br></div><div>However, I agree with Chris's concerns about how useful this is in LLVM. While I've used it on projects where it provides tremendous value, with LLVM I often end up in the debugger anyways. I think the automatic debugger trapping is marginally more useful, but only marginally. Having my debugger discard the SIGABRT and continue isn't too hard. On the flip side, it might make crash reports from users much more useful (in the absence of, or prior to arriving at, a reduction). I think the cost is quite low, so maybe its worth it, but maybe it isn't.</div>
</blockquote></div><br><div>If this is done we should make sure the expressions operated on by the stream are only evaluated when the condition is false and !NDEBUG.</div><div><br></div><div>Since the macros that I'm used to are not available in LLVM, I'm often tempted to write this:</div><div><br></div><div>#ifndef NDEBUG</div><div>if (!cond) {</div><div> dbgs() << something_expensive_to_lookup;</div><div> assert(false);</div><div>}</div><div>#endif</div><div><br></div><div>I've gotten used to spending time in the debugger for simple problems just because using too many DEBUG() statements blows up the trace output, but nasty #ifdefs like this obfuscate the non-error code.</div><div><br></div><div>-Andy</div></body></html>