有没有理由在错误处理代码中没有广泛看到perror?

时间:2013-01-23 16:15:32

标签: c++ c error-handling

查看stackoverflow或其他地方的代码,似乎我很少看到perror()用于报告错误的确切性质。 printf更常见。这是一个指示perror有什么错误或缺失的指标吗?我希望它可以更频繁地使用,因为它可以提供更好的信息。

4 个答案:

答案 0 :(得分:7)

我个人更喜欢strerror(),它大致相同,但允许您将错误消息与printf或类似函数一起使用,为程序的编码人员或用户提供更多有用信息,具体取决于错误类型]。

例如:

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);
}

这样,我们也知道WHICH文件(说它是一个复制文件的程序,perror不一定会告诉你它是“源”还是“destionation”)。

如果错误是编程错误[或“预计不会出错的东西”],你也可以这样做:

#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); 

... 

假设您不希望删除“config.txt”,作为一个例子[一般情况下编程非常糟糕,但也许有正当理由......]

答案 1 :(得分:2)

perror()不会准确地给出发生错误的行号,而printf()会帮助您识别打印时的确切行。所以我认为它在调试方面更有帮助,我知道的perror()并没有错......

答案 2 :(得分:1)

如果在进行标准库调用之前将errno设置为零并且该调用失败并且是使用errno来描述失败原因的调用之一,那么perror和{ {1}}可能会提供有用的解释。大多数人不关注strerror,更不用说如何正确使用它了。这是一个更简单的时间的神器。

答案 3 :(得分:0)

由于我正在使用C ++,因此我不使用printf()和co,并且经常在启动时调用sync_with_stdio(false)。此外,该功能的问题是它只允许在本地打印错误。我经常会遇到这样的事情:

// setting errno
if(!foo1(bar))
    throw_errno_exception("foo1");

// returning errorcode
if(int e = foo2(bar))
    throw_exception(e, "foo2");

首先,并非每个函数都使用errno。特别是对于新代码,我也不会这样做,而只是返回带有相应错误代码的int。因此,对于那些“新”函数,我必须在使用perror()之前手动设置errno。但是,我也不希望这样,因为失败的函数和我捕获异常的地方之间通常存在相当大的差距。

现在,在C中,您无法像在C ++异常中那样在堆栈中传递其他信息。因此,在C中更重要的是记录实际失败的函数以及它失败的地方的任何上下文。