在调用函数然后检查errno之前需要清理errno吗?

时间:2014-08-14 18:32:27

标签: c++ linux

  1. 在调用函数之前,我们是否需要将errno重置为零?见下面的代码。现在方案是a_dest_path是现有目录。但是当我执行代码时,它总是尝试mkdir但返回错误表示无法创建目录,因为它存在。在GDB中,我在调用errn之前检查opendir() o,errno为2.并且在调用errno期间似乎opendir()未设置为零。因此,在调用errno之前,我需要将opendir()重置为零吗?

  2. errno可能会在system()次调用中更改,然后在我的else if分支中,我会检查system()但不是opendir()的结果。因此,在opendir()之后,是否需要将errno分配给变量,然后在if..elseif..else分支中检查此变量?

  3. DIR *dp = opendir(a_dest_path.c_str());
    if (errno == ENOENT) {
        string mkdir_comman = "mkdir " + a_dest_path;
        system(mkdir_command.c_str());
    } else if (errno == ENOTDIR) {
        printf("Destination %s exists but is not directory\n", a_dest_path.c_str());
        return k_error_not_directory;
    } else if (errno == 0) {
        closedir(dp);
    }
    

3 个答案:

答案 0 :(得分:5)

不,在调用函数之前无需重置errno,因为the contract reads

  

opendir()fdopendir()函数返回指针          目录流。出错时,会返回NULL,并设置errno          适当。

测试返回值,只在实际出现错误时查看errno

realloc是一个罕见的函数示例,在特定情况下,如果不查看errno就无法将错误与成功区分开来,但如果需要消除歧义,则会清除错误。)

答案 1 :(得分:3)

errno仅在发生实际错误后才有意义。您必须先检查错误情况,然后查看errno,例如:

DIR *dp = opendir(a_dest_path.c_str());
if (dp) {
    closedir(dp);
} else {
    if (errno == ENOENT) {
        string mkdir_comman = "mkdir " + a_dest_path;
        system(mkdir_command.c_str());
    } else if (errno == ENOTDIR) {
        printf("Destination %s exists but is not directory\n", a_dest_path.c_str());
        return k_error_not_directory;
    } else {
        // some other error...
    }
}

答案 2 :(得分:0)

在您的示例中,正如其他人所述,无需重置 errno

然而,有极少数函数返回一个数字,对于它们来说,没有一个数字可以 100% 表示发生了错误。在这少数情况下,则需要重置 errno

此类函数的一个示例是 strtol()。出错时返回-1。如果你真的想知道用户是否通过了 "-1" 或者是否发生了错误,那么你想要这样做:

errno = 0;
long r = strtol(input, &end, 10);
if(r == -1 && errno != 0)
    ...handle the error...

在大多数情况下,此类函数会在其 DESCRIPTIONRETURN VALUE 手册部分明确说明问题。

正如其他人提到的,一个函数返回一个指针,当它返回一个 nullptr 时它代表一个错误,那么你不需要重置 errno,因为你应该只在函数返回 {{ 1}}。

nullptr