【问题标题】:Returning errno from main [closed]从主返回 errno [关闭]
【发布时间】:2018-06-23 18:24:30
【问题描述】:

我的代码结构如下:

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

我以为我会从 main.js 返回一些有意义的错误。但是太懒了。现在我想稍微缩小我的代码。我想按以下方式构造我的代码:

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

这样做是个好习惯吗?

【问题讨论】:

  • 不是一个很好的密切理由,因为答案肯定最好不要主要基于选项,而是基于事实(请参阅this answer below)。
  • 目前看不到任何基于意见的答案。这些答案为我提供了一些有价值的信息。

标签: c errno


【解决方案1】:

errno 变量可以被perrorclose 修改。如果你想返回 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
}

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

我以为我会从 main 中返回一些有意义的错误。

在第一个版本中,您会从 main 中返回有意义的错误。如果您的程序返回 -1,则您知道第一个 if 失败。如果你的程序返回 -2 你知道你的第二个if 失败了。从 perror 消息中,您知道 errno 具有什么值。如果你知道什么函数失败了,errno 值是什么,你可以查看函数手册中关于 errno 值的解释。如果你的程序返回 errno,你不知道哪个调用失败了。而且在不知道哪个调用失败的情况下,您不知道如何解释 errno 值。

【讨论】:

  • 叹息。我想我应该坚持第一种(更乏味的)做事方式。
【解决方案2】:

您可以这样做,(假设您纠正了@Kamil Cuk 提出的问题)但您应该知道许多(大多数?)shell 只从程序中读取 8 位退出代码。这意味着如果 errno 值超过 255 并且您的程序返回其中一个错误,shell 将错误地报告您的错误代码。在http://www.ioplex.com/~miallen/errcmp.html 可以看到,errno 代码至少达到了值 252,(HP-UX 11.22 的“功能未实现”)所以这不是一个不合理的情况。

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

【讨论】:

  • 你可以那样做”,最好不要,因为,不,这不一定有效。因为errno 很可能被修改为程序退出时调用的任何函数。 (close() 在 OPs 2nd sn-p 中)。
  • @user109923 你的观点被采纳了。
  • @alk 是的,我假设它是正确实施的。我已经编辑了我的答案以澄清这一点。
猜你喜欢
  • 2014-01-30
  • 1970-01-01
  • 1970-01-01
  • 2016-12-26
  • 2014-07-24
  • 1970-01-01
  • 1970-01-01
  • 2014-03-10
  • 2016-07-08
相关资源
最近更新 更多