asserts (was Re: Checking Exit Codes)
Dave Burton
daveb at nostromo.austin.ibm.com
Wed Oct 31 05:48:43 AEST 1990
[ follow-ups redirected to comp.unix.programmer ]
In article <18658 at rpp386.cactus.org> jfh at rpp386.cactus.org (John F. Haugh II) writes:
|so, you will always assume that failing asserts never return? this
|means that your portable programs aren't.
The only way for a SVR2,3 assert() to return is _if_ SIGIOT is not
SIG_DFL. Most programs do not blithely SIG_IGN all signals. Further,
BSD/AIX/other asserts can _never_ return. So, yes, I always% assume
failing asserts() never return - that is their design. As for portability,
see below.
% given the caveat of SIGIOT peculiarities on SVR2,3 systems
|you could splatter your code with feature test macros for each
|and every one of those versions you listed, with special behavior
|to be followed. or you could take the easy way out, listen to
|your uncle fred, and just put an exit after failing assert()
|calls. this is easy, portable, and foolproof. it has the novel
|property that it always works.
It is obvious that you did not read what I wrote.
Repeat after me: "assert() is a macro, not a function."
If I put an exit() after an assert() call, it looks like:
#include <assert.h>
#include <signal.h>
main(argc) {
signal(SIGIOT, SIG_IGN);
assert(argc==2);
exit(1);
printf("argc is equal to 2\n");
}
Well, clearly this won't work. How about:
if (assert(argc==2) == -1)
exit(1);
Oh. Syntax error. Looking at assert.h reveals the definition:
#define assert(EX) if (EX) ; else _assert("EX", __FILE__, __LINE__)
Gee, "Uncle Fred", how do you put a conditional exit() in your code?
Surely you wouldn't do:
assert(argc==2),exit(1);
would you? What happens when NDEBUG is #define'd? Syntax error.
The only way to put an exit() after a failing assert() is to
rework the macro, which is not portable.
|but the kernel assert() function is not defined
|in the System V Programmer's Reference Manual sitting next to me.
|i checked the namelist on the kernel running here.
This could be my fault for not accurately describing the kernel assert
mechanism for you. The _macro_ name (it _won't_ appear in any namelist,
just like user asserts) is ASSERT(). It invokes assfail() the same way
user assert() invokes _assert(). And assfail() will _not_ return.
Refer to <sys/debug.h>.
|no assert. hmmm.
|perhaps this is another IBMism? always assume the worst; never
|count on undocumented behavior or nonstandard features.
Perhaps you should do a little more research before sermonizing?
|the point of this article was to illustrate that ignoring unexpected
|returns can lead to unexpected results, not to serve as an
|oppurtunity for someone to research every version of assert().
I admit, I did look at the sources to verify my understanding
before posting to the net. That's generally considered wise.
Perhaps you would fare better if you did the same.
--
Dave Burton
inet: daveb at bach.austin.ibm.com
uucp: cs.utexas.edu!ibmchs!auschs!nostromo!daveb
More information about the Comp.unix.programmer
mailing list