C 失败时返回代码。肯定还是否定?

C 失败时返回代码。肯定还是否定?,c,linux,return,errno,C,Linux,Return,Errno,在Linux的特殊情况下,C程序可能无法执行。 示例:您分配了一些空间,但操作系统拒绝了它 char *buffer = (char *) malloc(1024); if (buffer == NULL) return ENOMEM; 此故障由发送到操作系统的返回代码标记 返回代码0(EXIT_SUCCESS)被标记为成功执行 非0的返回代码被标记为失败 所以我的问题是,当程序检测到错误时,约定是什么。 它应该返回正返回码还是负返回码? 我的教授告诉我,在UNIX/Linux中,

在Linux的特殊情况下,C程序可能无法执行。 示例:您分配了一些空间,但操作系统拒绝了它

char *buffer = (char *) malloc(1024);
if (buffer == NULL)
    return ENOMEM;
此故障由发送到操作系统的返回代码标记

  • 返回代码0(EXIT_SUCCESS)被标记为成功执行
  • 非0的返回代码被标记为失败
所以我的问题是,当程序检测到错误时,约定是什么。 它应该返回正返回码还是负返回码?

我的教授告诉我,在UNIX/Linux中,所有方法都返回一个否定的错误代码。但是errno代码都是正整数。此外,中EXIT_FAILURE的define语句是1,一个正整数。 那么我的代码应该是这样的:

char *buffer = (char *) malloc(1024);
if (buffer == NULL)
    return -ENOMEM;
int allocate_buffer(char *buffer) {
    buffer = malloc(1024);
    if (buffer == NULL) {
        errno = ENOMEM;
        return -1;
    }
    return 0;
}
还是像上面的代码?我从Linux内核模块了解到,在大多数情况下,它们在出现故障时会返回一个否定的错误代码


感谢您的帮助。

5.1.2.2.3程序终止

如果主函数的返回类型是与int兼容的类型, 从初始调用到主函数的返回相当于 使用main返回的值调用exit函数 作为其论据的功能;11) 到达终止 main函数返回一个值0。如果返回类型不是 与int兼容,终止状态返回到主机 环境是不具体的

7.22.4.4退出功能:

最后,将控件返回到主机环境。如果 状态为零或退出成功,这是 返回状态“成功终止”。如果status的值为 退出失败,一种状态的实施定义形式 返回不成功的终止。否则,状态将改变 返回的是已定义的实现


我发现这是自描述性的。

对于程序中未进一步指定的错误代码,惯例是使用
EXIT\u FAILURE
。它将被定义为操作系统识别为故障退出代码的值


errno.h
中定义的宏不是进程的返回码,而是程序执行期间的错误的返回码。标准库将把它们放在全局
errno
中,如果您愿意,还可以将它们用作函数的返回代码。其中三个由C标准规定:
EDOM
EILSEQ
ERANGE
。POSIX还规定了更多内容。不要将它们用作
main()
(或
exit()
)的返回代码。

通常,Linux程序在成功时返回0,在失败时返回非零。也有一些例外(例如grep,它的值表示它是否找到了匹配项)。原因是bash提示符将true定义为0,将false定义为1,因此它使脚本编写变得简单:

somecmd && action "if succesful"

但这就是程序本身。对于程序内部的代码,通常有多种约定。一种常见的方法是,成功时返回0(或正),失败时返回负。这背后的原因是,所有指令集(我知道)都有一个分支(如果为零),或者分支(如果小于零)指令,这意味着它只有一条指令来进行比较(而不是必须进行比较,然后在比较匹配的情况下进行分支)。

UNIX/Linux上的进程退出代码,
main()
中的
return
语句或对
exit()
的调用在0-255范围内未签名

从函数中,它可以是您想要的任何类型。许多库函数在出错时返回
-1

然而,这并不总是可能的,尤其是通常返回指针的函数。按照惯例,这些函数在出错时返回
NULL
,例如
fopen()
malloc()

这些返回代码仅表示发生了错误,而不是错误是什么,通常(错误时)全局
errno
也设置为正错误代码,以提供更多信息。看

所以我的问题是,当程序检测到 错误。它应该返回正返回码还是负返回码

你没有做出选择的奢侈(或责任)。一般来说,从C的角度来看,您的选择分为三类:

  • 您指定的退出状态为
    0
    exit\u SUCCESS
    (不一定不同)。这表示成功完成

  • 您指定的退出状态为退出失败。这表示未成功完成

  • 您指定的退出状态是其他状态

向主机环境发送信号的结果是在每种情况下都定义了实现,尽管在第一种情况下,它表示成功,在第二种情况下,它表示失败

现在,在实现POSIX
exit()
语义的Linux和其他操作系统上,实现定义已标准化:

状态值可以是
0
EXIT\u SUCCESS
EXIT\u FAILURE
,或者任何其他值,但是只有最低有效的8位(即
status&0377
)可以从
wait()
waitpid()
>获得

(;增加强调)。这些是传统的UNIX语义;只有您指定的退出状态的最低有效8位是重要的,因此签名丢失。然而,POSIX的当前版本继续说:

完整值应可从
waitid()
获得,并在
siginfo\u t
中传递给
SIGCHLD
的信号处理程序

因此,如果父进程知道查找负数,则可以将负数传递给它。然而,总的来说,这是不行的。特别是,如果父进程
int allocate_buffer(char *buffer) {
    buffer = malloc(1024);
    if (buffer == NULL) {
        errno = ENOMEM;
        return -1;
    }
    return 0;
}