Richard Harter’s World
Site map
May 2008
Mathcomp
email

Checking arguments in C functions

Little grasshopper asked: should one check arguments in C functions?

There are three separate issues here: (A) should you check arguments, (B) how should you check them, and (C) what should you do about it if there is an error. Obviously there is quite a bit of room for variations in style. However here are some suggestions.

(A) Should you test the validity of the arguments? In general, the answer is yes. If you do not, an unexpected faulty argument will produce a mystery bug. These kind of bugs can be doubly hard to find because (1) you “know” the argument is okay, and (2) the invalid argument violates the implicit assumptions in the code.

That said, there are situations where it is reasonable to omit checks. This can happen when the function is an internal function within a controlled scope where callers guarantee the validity of the arguments.

An alternative to checking arguments is to write the code so that all arguments are valid. Valid may merely mean reporting an error back to the caller.

(B) How should you test them? In my opinion, the obvious way to do it is also the worst way to do it if one is programming on any scale. The obvious way has the form

    if (some_condition) {some_action}
where some_condition is a failure condition, and some_action typically consists of printing an error message and exiting with EXIT_FAILURE.

The first thing that is wrong with this kind of code is that it almost never gets tested adequately. (You, dear reader, always test your code thoroughly but the TOG, the other guy, doesn’t.)

The second thing (minor but a source of problems) is that condition is backwards; that is, what one should be doing is what assert does – specify what should be true of the arguments.

Assert is the obvious (and useful) choice for code in a test mode or for code that is never going to see the light of day outside of your personal environment. In serious code, however, assert is inadequate. My choice is to roll my own that is coupled with an error handler.

(C) What should you do about it if there is an error? There are a number of things wrong with writing your own action code for each test: (1) In the nature of things the action code is likely to be untested; (2) Often the function is the wrong place to decide what to do; (3) It preempts having a coordinated error management policy.

My policy for programs of any size is to write an error handler as a program wide utility. The error handler takes care of writing error reports to an error log file. An error report includes information about the specific fault and system state information. The response to the error that it takes depends on options passed to it. Thus, the default action might simply be to write an error report and exit. However one could have the option to pass it a callback function which takes corrective action and continue. If one creates a my_assert macro, another option might be to have the function return with an error indicator to the calling function. Usw.

Your specific strategy might be quite different from mine. However the main point I am making is that you should have a coherent error management strategy that is robust and works for you.


This page was last updated May 1, 2008.

Richard Harter’s World
Site map
May 2008
Mathcomp
email