The assert() macro is for catching programmer errors. For example:
void foo(char *bar)
{
assert(bar!=NULL);
/* ... */
}
Basically what you're saying here is that bar should not be NULL under any circumstances. If it is NULL, the programmer has made a mistake. If bar happens to be NULL, an implementation-defined diagnostic is written to stderr, abort() is called and your program stops executing. This is a useful tool as it tends to catch some otherwise difficult to find errors.
When NDEBUG is defined, all assert()'s are stripped out of your program. The idea with assert() is that you use it during development to catch your own (the programmer's) mistakes and then when you release your code, you remove all your assert()s by defining NDEBUG.
Some people use assert() as a substitute for error checking but this goes against the intention of assert() and is generally considered bad programming practice. Imagine your users' confusion when your program suddenly crashes and a cryptic (cryptic to the user) error message appears. This is a debatable issue though and reasonable people disagree in some contexts about this use of assert().
setjmp() is used to save state information at a particular point in the program. longjmp() is used to return to the place that setjmp was originally called, using the same argument passed to setjmp as longjmp()'s 1st argument.
When longjmp() is called execution continues at the point where the corresponding setjmp() was called and the 2nd argument to longjmp() is used as setjmp()'s return value. The 1st call to setjmp() always returns 0, therefore calling longjmp() with the 2nd argument as a non-zero value allows you to write code that differentiates between the 1st call to setjmp() and a subsequent call to longjmp().
Maybe an example would make the above more clear:
jmp_buf env; /* opaque type used to save state info */
/* ... */
if (setjmp(env)==0) {
/* Execution continues here the 1st time setjmp() is called */
} else {
/* Execution continues here on return from
* a longjmp() call that has env as its 1st
* argument
*/
}
/* ... sometime later ... */
/* Execution continues at the else above */
longjmp(env,1);
Think of it as an extended 'goto' that allows quite a bit more flexibility as the jumps can occur across functions. By the same token, these functions, like goto, can make your code into spaghetti code if abused.
HTH,
Russ
bobbitts@hotmail.com