Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

assert.h?....setjmp.h?.... 1

Status
Not open for further replies.

jdubowy

Programmer
Mar 1, 2001
13
US
One very general question is if anybody can explain when/how to use the assert(expr) macro (from assert.h).......
Next, what do setjmp() and longjmp() do? I have a vague idea that they somehow save the addresses of all automatic variables, as well as other variables currently saved in memory. However, when is it that such saving of the heap(?) is necessary, and how are these functions called?....
any explanation is appreciated.
thanks
 
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
 
I put this in a followup e-mail to jdubowy which gives some more info on setjump() and longjmp():

setjmp()/longjmp() are usually used for error handling. For example, dealing with errors where an error can occur in any number of functions and you want to return control to where the chain of function calls started if an error occurs. In this case you would call setjmp() and then run through the chain of functions. In each function you might have a series of conditional calls to longjmp() like this:

if (error) {
setjmp(env,1);
}

Your setjmp() call might look something like this:

if (setjmp(env)==0) {
/* Call functions */
} else {
/* An error must have occured, do cleanup or whatever */
}

If you're familiar with C++ or Java notice how the pattern above is similar to:

try {
/* Call functions */
} catch (whatever e) {
/* Error */
}

Russ
bobbitts@hotmail.com
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top