Есть ли разница между функциями on_exit() и atexit()?
Вопрос
Есть ли разница между
int on_exit(void (*function)(int , void *), void *arg);
и
int atexit(void (*function)(void));
кроме того факта, что функция, используемая on_exit, получает статус выхода?
То есть, если меня не волнует статус выхода, есть ли смысл использовать тот или иной?
Редактировать: Многие ответы предостерегают от on_exit
потому что это нестандартно.Если я разрабатываю приложение для внутреннего корпоративного использования и гарантированно будет работать в определенных конфигурациях, стоит ли мне об этом беспокоиться?
Решение
В соответствии с эта ссылка Я нашел, кажется, есть несколько отличий. on_exit
позволит вам передать аргумент, который передается в on_exit
функция, когда она вызывается...что может позволить вам установить некоторые указатели для выполнения некоторой работы по очистке, когда придет время выйти.
Более того, оказывается, что on_exit
это была специфическая функция SunOS, которая может быть несовместима со всеми платформами...поэтому вы можете придерживаться atexit, несмотря на то, что он более строгий.
Другие советы
Вы должны использовать atexit()
если возможно. on_exit()
является нестандартным и менее распространенным.Например, он недоступен в OS X.
Кернел.орг - on_exit()
:
Эта функция поступает из Sunos 4, но также присутствует в Libc4, Libc5 и Glibc.Этого больше не происходит в Solaris (SunOS 5).Избегайте этой функции и вместо этого используйте стандартный Atexit (3).
Разница в том, что atexit
это C и on_exit
какое-то странное расширение, доступное в GNU и черт знает что еще в системах Unixy (но НЕТ часть POSIX).
@Натан, я не могу найти функцию, которая вернет код завершения текущего запущенного процесса.Я ожидаю, что он еще не установлен в тот момент, когда atexit()
так или иначе называется.Под этим я подразумеваю, что среда выполнения знает, что это такое, но, вероятно, не сообщила об этом ОС.Хотя это в значительной степени всего лишь предположение.
Похоже, вам придется либо использовать on_exit()
или структурируйте свою программу так, чтобы код выхода не имел значения.Было бы разумно, если бы последний оператор вашей основной функции переворачивал глобальное значение. exited_cleanly
переменная в true.В функции, с которой вы регистрируетесь atexit()
, вы можете проверить эту переменную, чтобы определить, как завершилась программа.Это даст вам только два состояния, но я ожидаю, что этого будет достаточно для большинства нужд.При необходимости вы также можете расширить этот тип схемы, чтобы поддерживать больше состояний выхода.
@Натан
Сначала посмотрите, есть ли еще один вызов API для определения статуса выхода...быстрый взгляд, и я его не вижу, но я плохо разбираюсь в стандартном C API.
Простая альтернатива — иметь глобальную переменную, в которой будет храниться статус выхода...по умолчанию — неизвестная причина ошибки (в случае ненормального завершения программы).Затем, когда вы вызываете выход, вы можете сохранить статус выхода в глобальном масштабе и получить его из любой функции atexit.Это требует тщательного сохранения статуса выхода перед каждым вызовом выхода и явно не идеально, но если нет API и вы не хотите рисковать on_exit
не быть на платформе...возможно, это единственный вариант.