wrapping the macro's body in: do { ... } while (false) would make the the macro a proper statement so that: if (cond) ASSERT(some_other_cond); else do_something_cool (); compiles as expected. IMO, it would work as such #define ASSERT_STM(cond,expr) On Tue, Jul 26, 2011 at 6:36 PM, Reid Kleckner <reid.kleckner at gmail.com>wrote:> He wants to be able to resume execution from the debugger after > assertion failure. > > Reid > > On Tue, Jul 26, 2011 at 8:07 PM, Alistair Lynn <arplynn at gmail.com> wrote: > > Hi- > > > >> Yep, but tripping the debugger is highly non-portable. > > > > You're suggesting that inline asm is more portable than calling abort? > > > > Alistair > > > > _______________________________________________ > > LLVM Developers mailing list > > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > > > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110726/ce7a2037/attachment.html>
sorry, my previous message got sent too early I think the macro should look something like this: #define ASSERT_STRM(cond,expr) \ do { if (cond) { std::cerr << expr << std::end; assertion_trap (); } } while (false) On Tue, Jul 26, 2011 at 7:57 PM, Nathan Jeffords <blunted2night at gmail.com>wrote:> wrapping the macro's body in: > > do { ... } while (false) > > would make the the macro a proper statement so that: > > if (cond) > ASSERT(some_other_cond); > else > do_something_cool (); > > compiles as expected. > > IMO, it would work as such > > #define ASSERT_STM(cond,expr) > > > On Tue, Jul 26, 2011 at 6:36 PM, Reid Kleckner <reid.kleckner at gmail.com>wrote: > >> He wants to be able to resume execution from the debugger after >> assertion failure. >> >> Reid >> >> On Tue, Jul 26, 2011 at 8:07 PM, Alistair Lynn <arplynn at gmail.com> wrote: >> > Hi- >> > >> >> Yep, but tripping the debugger is highly non-portable. >> > >> > You're suggesting that inline asm is more portable than calling abort? >> > >> > Alistair >> > >> > _______________________________________________ >> > LLVM Developers mailing list >> > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >> > >> >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >> > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110726/7c10b60f/attachment.html>
Great suggestion - what should the !NDEBUG version look like? On Tue, Jul 26, 2011 at 8:01 PM, Nathan Jeffords <blunted2night at gmail.com>wrote:> sorry, my previous message got sent too early > > I think the macro should look something like this: > > #define ASSERT_STRM(cond,expr) \ > do { > if (cond) { > std::cerr << expr << std::end; > assertion_trap (); > } > } while (false) > > > On Tue, Jul 26, 2011 at 7:57 PM, Nathan Jeffords <blunted2night at gmail.com>wrote: > >> wrapping the macro's body in: >> >> do { ... } while (false) >> >> would make the the macro a proper statement so that: >> >> if (cond) >> ASSERT(some_other_cond); >> else >> do_something_cool (); >> >> compiles as expected. >> >> IMO, it would work as such >> >> #define ASSERT_STM(cond,expr) >> >> >> On Tue, Jul 26, 2011 at 6:36 PM, Reid Kleckner <reid.kleckner at gmail.com>wrote: >> >>> He wants to be able to resume execution from the debugger after >>> assertion failure. >>> >>> Reid >>> >>> On Tue, Jul 26, 2011 at 8:07 PM, Alistair Lynn <arplynn at gmail.com> >>> wrote: >>> > Hi- >>> > >>> >> Yep, but tripping the debugger is highly non-portable. >>> > >>> > You're suggesting that inline asm is more portable than calling abort? >>> > >>> > Alistair >>> > >>> > _______________________________________________ >>> > LLVM Developers mailing list >>> > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>> > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>> > >>> >>> _______________________________________________ >>> LLVM Developers mailing list >>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>> >> >> > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > >-- -- Talin -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110726/4af71a4b/attachment.html>
Here's an example of how this would be used: In the constructor for ConstantVector, there's an assert: assert(C->getType() == T->getElementType() && "Initializer for vector element doesn't match vector element type!"); I would change this to: ASSERT_STRM(C->getType() == T->getElementType(), "Initializer for vector element " << I - V.begin() << " with type " << C->getType() << " doesn't match vector element type " << T->getElementType()); With more detailed assertions like this, a much larger class of programmer errors can be diagnosed without having to go into the debugger. Because the stream is a raw_ostream, LLVM types and values can easily be printed to the stream without having to convert them to string form. Based on the suggestions so far, I'm guessing that the macro would look like this: #include "llvm/Support/raw_ostream.h" namespace llvm { // This just writes out "Assertion Failed" and the file/line number in // a form that IDEs can parse. void assertion_prologue(const char * file, unsigned line); // This does the trap or abort or whatever. void assertion_trap(); #if NDEBUG #define LLVM_ASSERT_STRM(expr, args) do {} while false // Alternatively // #define LLVM_ASSERT_STRM(expr, args) (void)0 #else /// Assertion macro that acts as an error output stream. Typical usage: /// /// LLVM_ASSERT_STRM(a != b, "Expected " << a << " == " << " b") #define LLVM_ASSERT_STRM(expr, args) \ do { if (!(expr)) { \ assertion_prologue(__FILE__, __LINE__); \ errs() << args << "\n"; \ assertion_trap(); \ } while (false) #endif /// Assertion macro that behaves like standard C assert(). #define LLVM_ASSERT(expr) LLVM_LLASSEERT_STRM(expr, #expr) /// Assertion macro that expects two values to be equal, as defined /// by the equality operator. #define LLVM_LLASSERT_EQ(expected, actual) \ LLVM_LLASSEERT_STRM(expected == actual, "Expected: " << expected << \ " but actually was " << actual) I'm open to suggestions on naming - LLVM_ASSERT_STRM may be a little too verbose, but you have to be careful about name collisions since macros aren't namespaced. In particular I want to avoid any overlap with Google Test, which has a bunch of ASSERT_XXX macros. On Tue, Jul 26, 2011 at 8:01 PM, Nathan Jeffords <blunted2night at gmail.com>wrote:> sorry, my previous message got sent too early > > I think the macro should look something like this: > > #define ASSERT_STRM(cond,expr) \ > do { > if (cond) { > std::cerr << expr << std::end; > assertion_trap (); > } > } while (false) > > > On Tue, Jul 26, 2011 at 7:57 PM, Nathan Jeffords <blunted2night at gmail.com>wrote: > >> wrapping the macro's body in: >> >> do { ... } while (false) >> >> would make the the macro a proper statement so that: >> >> if (cond) >> ASSERT(some_other_cond); >> else >> do_something_cool (); >> >> compiles as expected. >> >> IMO, it would work as such >> >> #define ASSERT_STM(cond,expr) >> >> >> On Tue, Jul 26, 2011 at 6:36 PM, Reid Kleckner <reid.kleckner at gmail.com>wrote: >> >>> He wants to be able to resume execution from the debugger after >>> assertion failure. >>> >>> Reid >>> >>> On Tue, Jul 26, 2011 at 8:07 PM, Alistair Lynn <arplynn at gmail.com> >>> wrote: >>> > Hi- >>> > >>> >> Yep, but tripping the debugger is highly non-portable. >>> > >>> > You're suggesting that inline asm is more portable than calling abort? >>> > >>> > Alistair >>> > >>> > _______________________________________________ >>> > LLVM Developers mailing list >>> > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>> > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>> > >>> >>> _______________________________________________ >>> LLVM Developers mailing list >>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>> >> >> > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > >-- -- Talin -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110726/43267dcc/attachment.html>