我有这样一种结构的代码:
main(){
if(...){
perror(... < 0);
res = -1;
goto cleanup;
}
...
if(... < 0){
perror(...);
res = -2;
goto cleanup;
}
...
cleanup:
close(fd);
return res;
}
我认为我会从main中返回一些有意义的错误。但是太懒了。现在,我想缩一些代码。我想通过以下方式构造代码:
...
if(... < 0){
perror(...);
goto cleanup;
}
...
if(... < 0){
perror(...);
goto cleanup;
}
cleanup:
close(fd);
return errno; // return from main
以这种方式进行操作是一种好习惯吗?
答案 0 :(得分:4)
errno变量。如果要返回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
失败了。从错误消息中,您知道errno的值。如果知道什么功能失败以及errno值是什么,则可以查看功能手册以获取errno值的解释。如果程序返回errno,则您不知道哪个调用失败。而且,在不知道哪个调用失败的情况下,您也不知道如何解释errno值。
答案 1 :(得分:4)
您可以这样做((如果您纠正了@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也可能是一个问题,但考虑到信号数量几乎没有增长根本我认为这没什么问题。