Is there a reason why perror isn't very common in error handling code?
Looking at the code on stackoverflow or elsewhere, I rarely seem to see perror () being used to report the exact nature of the error. printf is much more common. Is this an indicator that something has happened or gone without fear? I expect it to be used much more often given that it provides better information.
source to share
My personal preference strerror()
is that it does roughly the same thing, but allows the error message to be used in conjunction with printf or a similar function that provides additional usefulness [to the coder or user of the program, depending on the type of error].
For example:
errno = 0;
FILE *f = fopen(argv[1], "rb");
if (!f)
{
fprintf(stderr, "File %s open failed: error code %d ('%s')\n",
argv[1], errno, strerror(errno));
exit(1);
}
So we also know which file is WHICH (say it's the program that copies the file, perror won't necessarily tell you if it was "source" or "delete").
If the error is related to programming errors [or "things that shouldn't be wrong"], you can also do something like this:
#define UNEXPECTED(cond) do { if (cond) { do_unexpected(errno, #cond, __FILE__, __LINE__); } while(0)
void do_unexpected(int err, const char* cond, const char *file, int line)
{
fprintf(stderr, "Unexpected error %s [errno=%d, errstr=%s] at %s:%d",
cond, err, strerror(errno), file, line);
exit(1);
}
errno = 0;
FILE *config = fopen("config.txt", "r");
UNEXPECTED(!config);
...
Assuming you're not expecting to remove "config.txt" as an example [this is pretty bad programming in general, but there might be a good reason for this ...]
source to share
If you set errno
to zero before making a standard library call, and that call fails, and one of the calls it uses errno
to describe why it failed, then perror
it strerror
may provide a helpful explanation. Most people don't pay attention to errno
, much less how to use it correctly. This is an artifact of a simpler time.
source to share
Since I am using C ++ I do not use printf () and co and often call sync_with_stdio (false) on startup. Also, the problem with this feature is that it only allows you to print the error locally. What I do quite often, but something like this:
// setting errno
if(!foo1(bar))
throw_errno_exception("foo1");
// returning errorcode
if(int e = foo2(bar))
throw_exception(e, "foo2");
The first thing is that not every function uses errno. In particular, for new code, I would not do this either, but simply return int
with the appropriate error code. Thus, for these "new" functions, I would have to set errno manually before using perror()
. However, I don't want that either, because there is usually a gap between the failed function and the place where I won't catch the exception.
Now, in C, you have no way of passing additional information onto the stack, as is the case with C ++. For this reason, in C, it is more important to register the actual failed function and any context where it fails.
source to share