Есть ли разница между функциями on_exit() и atexit ()?

Есть ли разница между

   int on_exit(void (*function)(int , void *), void *arg);

и

   int atexit(void (*function)(void));

кроме того, что функция, используемая on_exit, получает статус выхода?

То есть, если я не забочусь о статусе выхода, есть ли причина использовать тот или другой?

Edit: многие ответы предупреждены противon_exit, потому что это нестандартно. Если я разрабатываю приложение, которое предназначено для внутреннего корпоративного использования и гарантированно работает на определенных конфигурациях, должен ли я беспокоиться об этом?

5 ответов

  1. Вы должны использоватьatexit(), если это возможно. on_exit()является нестандартным и менее распространенным. Например, он недоступен в OS X.

    Kernel.org — on_exit():

    Эта функция приходит от SunOS 4, но также присутствует в libc4, libc5 и
    glibc. Он больше не встречается в Solaris (SunOS 5). Избегайте этой функции и
    вместо этого используйте стандартный atexit(3).

  2. По этой ссылке я нашел, кажется, есть несколько отличий. on_exitпозволяет передать аргумент, который передается в on_exitфункцию при ее вызове… что может позволить вам настроить некоторые указатели, чтобы сделать некоторую работу по очистке, когда пришло время выйти.

    Кроме того, похоже, что on_exitэто была специфическая функция SunOS, которая может быть не совместима на всех платформах… таким образом, вы можете придерживаться atexit, несмотря на то, что он является более ограничительным.

  3. @Натан

    Сначала посмотрите, есть ли другой вызов API для определения статуса выхода… быстрый взгляд, и я не вижу, но я не очень хорошо разбираюсь в стандартном API C.

    Простой альтернативой является глобальная переменная, хранящая статус выхода… значение по умолчанию-неизвестная причина ошибки (если программа завершается ненормально). Затем при вызове exit можно сохранить состояние exit в глобальном и извлечь его из любых функций atexit. Это требует сохранения статуса выхода старательно перед каждым вызовом выхода, и явно не идеально, но если нет API, и вы не хотите рисковать on_exitне быть на платформе… это может быть единственным вариантом.

  4. @Nathan, я не могу найти функцию, которая вернет код выхода для текущего запущенного процесса. Я ожидаю, что он еще не установлен в точке, когда atexit()вызывается, в любом случае. Под этим я подразумеваю, что среда выполнения знает, что это такое, но, вероятно, не сообщил об этом в ОС. Это в значительной степени просто гипотеза, хотя.

    Похоже, вам придется использовать on_exit()или структурировать программу так, чтобы код выхода не имел значения. Было бы разумно, чтобы последнее утверждение в вашей основной функции переворачивало глобальную exited_cleanlyпеременную на true. В функции , с которой вы регистрируетесьatexit(), вы можете проверить эту переменную, чтобы определить, как программа вышла. Это даст вам только два состояния, но я ожидаю, что этого будет достаточно для большинства потребностей. Можно также развернуть этот тип схемы для поддержки большего количества состояний выхода при необходимости.

  5. Разница в том, что atexitэто C и on_exitкакое-то странное расширение, доступное на GNU и кто знает, что другие системы Unixy (но не часть POSIX).