constructing own error functions vs something like fprinf()

G

grocery_stocker

Why would someone go through the trouble of constructing an error
handling function using variable-length argument lists? Why not just
use something like printf()?
 
E

Eric Sosman

grocery_stocker said:
Why would someone go through the trouble of constructing an error
handling function using variable-length argument lists? Why not just
use something like printf()?

What if you want the message to go to something other
than an output stream -- a dialog box, perhaps?

What if you want to add "decorations" to the message
as provided -- line number, call stack, or the like?

What if you want to assign each error a "severity" and
route the message (or take other action) based on that
severity?

What if you want to do *any* kind of extra processing
when an error occurs, and would prefer to write the code
in just one place rather than in all two hundred spots where
an error might occur?

... and the beat goes on.
 
L

Lawrence Kirby

Why would someone go through the trouble of constructing an error
handling function using variable-length argument lists? Why not just
use something like printf()?

printf() isn't an error handling function, it just writes data to standard
output. This may not be appropriate for an error handling function, or the
error handling function may do other things too. Iven if you wanted only
an error reporting function that logs data to a stream, you might want
output formatted in a standardised way (e.g. with a timestamp in each
entry), you might want to control what is output (e.g. some sort of
logging level), and so on.

Also an error handling function can use printf(), or more specifically
vprintf() and similar functions. So it doesn't have to reimplement what
printf() does.

Lawrence
 
A

Anonymous 7843

Why would someone go through the trouble of constructing an error
handling function using variable-length argument lists? Why not just
use something like printf()?

Perhaps it's not as critical to others, but I dislike using varags
functions for error reporting. It's too easy to supply things that
don't match the format, or to dereference NULL or freed pointers. It's
difficult to create testing scenarios for error conditions, so you end
up with a situation where there is lots of error reporting, but none of
it is tested. When an error actually occurs, you run a great risk of
making the problem worse by using an untested, fancy interface that
encourages printing out corrupted data.

My own philosophy is to log contextual information well before the
error occurs (on a regular basis, so it is well tested; and before the
bulk of processing so it has not yet been corrupted), then at
the point of discovering the error just print out a constant string
along the lines of "there was a problem with the current blah's foobar
pointer."
 
R

Richard Tobin

Anonymous 7843 said:
My own philosophy is to log contextual information well before the
error occurs (on a regular basis, so it is well tested; and before the
bulk of processing so it has not yet been corrupted), then at
the point of discovering the error just print out a constant string
along the lines of "there was a problem with the current blah's foobar
pointer."

This only applies to a very limited kind of error handling. How would
you use it to report a syntax error in user input for example?

-- Richard
 
A

Anonymous 7843

This only applies to a very limited kind of error handling. How would
you use it to report a syntax error in user input for example?

User-input errors are easy to reproduce and test, so I would have no
quarrel with a sophisticated varargs thingy to print out a detailed
description of a syntax error.

Whether the remainder is "very limited" depends on the nature and
requirements of what you're doing. At the very least, I would
encourage people who choose to use a varargs error reporting thingy to
either use printf or fprintf directly, or to use their favorite
compiler's printf-like attribute (if available) on their custom error
reporting function so that lame argument mismatches don't crash your
program before you can even print the message.

For a more rigorous environment, combine that with some defensive
coding like implementation-specific checks on pointer locations, fflush
log files char by char (or setbuf), stop processing the va_arg list on
the first NULL or bad pointer, don't include any pointed-to data in
output unless all pointers pass the sanity checks, print and fflush the
constant part of the error message before processing dodgy arguments,
check pointers to strings (including the format string) to see if they
have non-printable chars or are more than 80 characters, and log the
date and time of the message, maybe even __FILE__ and __LINE__. Check
for low addresses on things passed in by value: the int you get might
be coming from something like (NULL)->struct.value. Check aligment
while you're at it. In environments which exceed the scope of ANSI C,
also consider printing out things like the thread number. Finally,
*test* the error reporting function by giving it deliberately garbaged
data of all kinds and make sure it doesn't choke.

Sure, this is overkill for a lot of programs, but if this makes the
difference between a truncated/garbaged log file and something that
helps you diagnose and fix a problem on a server in Kreplakistan at
3:00AM on Saturday night, you won't regret it.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,186
Latest member
vinaykumar_nevatia

Latest Threads

Top