从 main 返回 errno

Returning errno from main

我的代码结构如下:

main(){
 if(...){
  perror(... < 0);
  res = -1;
  goto cleanup;
 }
 ...
 if(... < 0){
  perror(...);
  res = -2;
  goto cleanup;
 }
 ...
cleanup:
 close(fd);
 return res;
}

我认为我会 return 从 main 中得到一些有意义的错误。但是太懒了。现在我想稍微缩减我的代码。我想按以下方式构建我的代码:

...
if(... < 0){
 perror(...);
 goto cleanup;
}
...
if(... < 0){
 perror(...);
 goto cleanup;
}
cleanup:
 close(fd);
 return errno; // return from main

这样做是一种好习惯吗?

errno 变量可以通过perror and close修改。如果你想 return errno,你需要先保存它,所以如果 perror 调用失败它不会修改你的 errno 值:

int main() {
    int errnosav = 0;
    ...
    errno = 0;
    if (some_function_that_modifies_errno() < 0) {
     errnosav = errno;
     perror(...);
     goto cleanup;
    }
    ...
    if (some_other_function_that_modifies_errno() < 0) {
     errnosav = errno;
     perror(...);
     goto cleanup;
    }
    cleanup:
     close(fd);
     return errnosav; // return from main
}

这与第一个版本相同,但您无法控制 returned 值。

I thought that I would return some meaningful errors from main.

对于第一个版本,您 return 来自 main 的有意义的错误。如果你的程序 returns -1,你知道第一个 if 失败了。如果你编程 returns -2 你知道你的第二个 if 失败了。从 perror 消息中,您知道 errno 的值是多少。如果知道是什么函数失败了,errno值是多少,可以查看函数手册对errno值的解释。如果你的程序 returns errno,你不知道哪个调用失败了。在不知道哪个调用失败的情况下,您不知道如何解释 errno 值。

你可以那样做,(假设你纠正了@Kamil Cuk 提出的问题)但你应该知道很多(大多数?)shells 只从中读取退出代码的 8 位程式。这意味着如果 errno 值超过 255 并且您的程序 returns 其中一个错误,shell 将错误地报告您的错误代码。在 http://www.ioplex.com/~miallen/errcmp.html 可以看到 errno 代码至少达到了值 252,("Function not implemented" 对于 HP-UX 11.22)所以这不是一个不合理的场景。

为了迂腐,shells 也呈现给用户退出代码 128+N,其中 N 是终止进程的信号编号,因此 N>127 也可能是一个问题,但考虑到信号的数量几乎没有增长,我认为这不是一个问题。