Þ   briarpig  » thorn  » demos  » assert


The idea of demos is explained here; a menu at top column right indexes actual topic specific demos. Here we demo asserts.

problem

     Wil likes to use assertions in his code, but the assert() macro in assert.h commits Wil to a specific narrow response, when more control would be better.

     So Wil simply clones assert() and calls the original inside the new clone, unless some other action seems better.

header

     The notional mu.h header file defines the following macros for yassert() and yexpect(), where the latter is not fatal like an assertion. yexpect() should log a message and a backtrace if possible, but not abort the process. (Todo: add likely() and unlikely() macros.)

// \brief do not assert: just msg & backtrace, go on extern int _mu_yexpect(const char* expr, // false expr const char* file, int line, const char* func); // __FUNCTION__ // \brief msg, maybe backtrace, then assert(): extern int _mu_yassert(const char* expr, // false expr const char* file, int line, const char* func); // __FUNCTION__ // \brief replace std assert (maybe backtrace 1st) #define yassert(x) \ ((void)((x)? 0 :_mu_yassert(#x,__FILE__,__LINE__,__FUNCTION__))) #define yexpect(x) \ ((void)((x)? 0 :_mu_yexpect(#x,__FILE__,__LINE__,__FUNCTION__)))

     Given this api, Wil simply uses yassert() everywhere instead of assert(), making it easy to change behavior of assertions in one central location.

     Wil likes to use assertions quite often in code to insist expected conditions are true at runtime in a manner that can't be ignored, by stopping a process cold if the condition ever fails.

     It's better to err on the side of too many assertions at first than too few: you can always remove too aggressive asserts after you understand circumstances better.

A submenu for demos appears below, letting you go to the page on a topic written as a demo (as the demos page defines it).

menu

     thorn: todo, names, fd, iovec, assert « Þ, log, run, hex, crc, buf, in, out, quote, escape, compare, file, deck, cow, slice, arc, blob, tree, rand, time, stat, hash, heap, node, primes, page, book, pile, stack, atomic, lock, mutex, thread, map, meter, list, iter, ctype

     (mu: toy, peg, imm, tag, box, symbol, token, number, bigint, class, method, reader, writer, eval, env, vm, gc, world, pcode, compiler, asm, lathe, lisp, smalltalk, design, weight, jar, card, harp, debug, profile)

     Some demos are stubs: todo is a demo guide. See toy for mu updates on language pages; names introduces naming schemes.

code

     Wil implements the code as below. The general idea is to provide as much context information as possible. A future demo will show how to display backtraces on Linux (using backtrace_symbols() and backtrace() functions from execinfo.h).

int _mu_yexpect(const char* ex, const char* fl, int ln, const char* fn) { if (!ex) ex = "nil"; fprintf(stderr, "<expect pid=%x tid=%lx exp='%s' at='%s:%u' in='%s()'/>\n", (int) ::getpid(), (long) pthread_self(), ex, fl, ln, fn); // maybe backtrace here; do not assert: just log msg return 0; // the yexpect macro expects return val } int _mu_yassert(const char* ex, const char* fl, int ln, const char* fn) { if (!ex) ex = "nil"; fprintf(stderr, "<assert pid=%x tid=%lx exp='%s' at='%s:%u' in='%s()'/>\n", (int) ::getpid(), (long) pthread_self(), ex, fl, ln, fn); // maybe backtrace before assert() for more info assert(!"_mu_yassert()"); return 0; // the yassert macro expects return val }

     Since there's very little story to assertions or the implementation, we might as well look at the format of messages that appear. Why the pseudo XML? Wil asks that question the other way: why not?

     Actually there's very little attempt to pursue XML with any rigor — it's simply a convenient meme to leverage so familiarity improves a reader's grasp of message formats.

     It's easy to imagine a short dialog here, between Wil and Dex about the use of XML; but since Wil tunes it out and stops listening, the conversation is rather one-sided. Dex thinks everything must be done properly. Wil thinks a casual gesture is better than nothing.

     "Did you know XML requires attributes to be quoted?" Dex inquired with a whiny tone of voice (about like his usual tone, actually).

     "Why yes, now you mention it," Wil ceded and rolled his eyes. "But I don't bother when brevity suits me."