关于atexit的三个问题

Three questions about atexit

RETURN 值:

   The atexit() function returns the value 0 if successful; otherwise, it returns a nonzero value.

示例:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void
bye(void)
{
    printf("That was all, folks\n");
}

int
main(void)
{
    long a;
    int i;

    a = sysconf(_SC_ATEXIT_MAX);
    printf("ATEXIT_MAX = %ld\n", a);

    i = atexit(bye);
    if (i != 0) {
        fprintf(stderr, "cannot set exit function\n");
        exit(EXIT_FAILURE);
    }

    exit(EXIT_SUCCESS);
}

我已阅读手册页和 Whosebug 问题,但仍然有关于 atexit 的三个问题:

  1. 什么时候 atexit 会失败,所以它会 return 非零值?请给我这样的演示,谢谢!
  2. 正如我们所知,bye 在调用 exit() 之前不会被调用。那么这是否意味着在调用 exit() 之前我们无法知道 atexit 的 return 值?如果是,那么第三个问题:
  3. 既然调用了exit(),那么if表达式如何执行呢?

atexit函数只是将函数添加到"list"。它本身不会调用您传递指针的函数。它也不会等待 exit 被调用,因为那样会使它变得毫无用处。因此它可以立即return(带有可能的错误代码),程序继续正常运行。

如果函数无法将您传递给其内部的函数指针添加到其内部 "list"(例如,它可能是一个有限的大小,并且您尝试添加更多)那么它将 return 以失败告终。同样,它将立即 return 而不是等待 exit 调用。

关于问题 1:atexit 仅设置函数 在退出时被调用 。它 returns 0 只要它能够 设置 那个函数,不管那个函数是否真的被调用过。

所以这回答了你的问题 2 和 3:不,你不需要等待 exit() 知道 atexit 的 return,所以评估 if也没问题。

as we know, bye will not be called until exit() is called. So does it mean we can not know atexit's return value until exit() is called?

我不确定我是否能完全理解你的想法,但误解似乎只是以下几点:

atexit() 报告成功仅表示 "I accepted whatever pointer you gave me, the function it points to will be called at exit"。这并不意味着对您的函数的实际 调用 会成功。

atexit() 报告错误因此意味着:"For whatever reason, I couldn't accept your pointer"。您的运行时环境可能内存不足,无法存储另一个指针或类似的东西。

atexit() 注册一个在程序退出时调用的函数,但它完成它的执行并 returns 控制调用上下文,而不等待程序终止。换句话说,如果不是为了注册传递的函数,它不会暂停程序执行。然后程序将从 atexit() 被调用的地方恢复,只有当它因任何原因终止时,才会调用注册的处理程序。

这应该可以回答您的问题 2:atexit() returns 一个值 "immediately",而不是在程序终止时。这也应该回答你的问题 3:当你调用 atexit() 时,不会调用 exit(),程序流程可以继续正常进行。

关于您的第一个问题,atexit() 失败的条件取决于特定的 libc 实现。在这些情况下,将返回负值并且 errno 将包含反映错误情况的代码。例如,在 GNU libc ate​​xit() returns 中,如果它无法为传递的错误函数分配条目,则会出现错误,请参阅 __new_exitfn() source code, called internally by atexit (source code here).