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.

+3


source to share


4 answers


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 ...]

+7


source


perror () will not tell you exactly the line number where the error occurred, and your printf () will help you figure out the exact line it prints on. So I find it more useful when debugging, nothing wrong with perror () that I know of ....



+2


source


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.

+1


source


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.

0


source







All Articles