I’ve never really wanted better looking assertions—just the fact that assert() failed is enough for me to rerun the program under a debugger (or look at the core file if there is one). What would be nice (for my uses) is the output going through syslog() (since I tend to write server software) but I can live without that.
Also, his example ASSERT3U(a++, ==, b) is bad, as one MUST NOT (per RFC-2119) use expressions with side effects in assert()—only bad things can happen otherwise.
ASSERT3U(a++, ==, b)
Strangely enough recruiters ask these kind of questions all the time. Passing value to a function using increment or decrement operator. It just makes me shudder.
That’s not necessarily bad though. It is bad for assert() because its behavior can change depending upon the definition of the macro NDEBUG (namely, assert() does nothing if NDEBUG is defined as the expression is not compiled at all).
I agree that the chosen example of ASSERT3U(a++, ... is not good. Omitted from this post, though, is the mandatory assertion form we provide via sys/debug.h: VERIFY(). The VERIFY family (including an analogous VERIFY3U, VERIFY3P, etc) is never compiled out, even for release builds. You can use it for critical things like bounds checks on buffers, or checks on critical return values (even from functions which mutate) where failure is believed not possible, etc.
We often use these routines in the operating system kernel. Crash dumps are often very large, sometimes aren’t completely written to disk (e.g., if the disk subsystem itself was the problem), and certainly contain private information that users aren’t always keen to expose to third parties – even for debugging purposes. In those cases, it can be quite helpful to have the panic message contain both the expected and the actual value in addition to the location of the assertion.
Agree. But something I did to work around the lack of core files (or the inability to obtain them) I wrote code to log a crash report to syslog which comes in handy for me. Yes, the code is probably not asynch safe, but I tried as best as I could, and so far, it’s worked fine for me.
Does the actual Solaris/Illumos code send the failure message to stdout as shown in the article? This seems like a textbook case of something that should go to stderr…
I cannot speak to the Oracle fork, but illumos uses stderr here. Most of the VERIFY and ASSERT macros are wrappers around assfail(), which in the C library has an explicit write to file descriptor 2 (i.e., STDERR_FILENO) in a way that tries to avoid as much of the stdio machinery as possible (it might be broken).
Yes I fixed that, thanks.
Yea you are right. The example could be better.
I added a notice about that.
assert() has a bug ;-)
Aghr… To quick! Thanks.
No mention of the standard assert.h? Don’t implement your own version of a standard function just because.