в GCC документы Я нашел -fuse-cxa-atexit
вариант и говорит следующее:
Эта опция требуется для полностью совместимой со стандартами обработки статических деструкторов
Так в чем же разница между этими двумя? В документах для __cxa_atexit
Я нашел следующее:
Функция __cxa_atexit () используется для реализации atexit ()
Я реализую статику в функциях (не спрашиваю почему), и мне было интересно, какой из 2 использовать для вызова деструктора.
И я думаю, у меня есть только atexit()
для MSVC? Это проблема?
Могу ли я просто использовать atexit()
везде и быть уверенным, что он будет вести себя так же, как реальные статические объекты в функциях?
__cxa_atexit()
определяется в Itanium C ++ ABI. Документ объяснил мотивация этой функции:
Стандарт C ++ требует, чтобы деструкторы вызывались для глобальных объектов при выходе из программы в обратном порядке построения. Большинство реализаций справились с этим, вызвав библиотеку C
atexit
рутина для регистрации деструкторов. Это проблематично, поскольку стандарт C 1999 года требует только того, чтобы реализация поддерживала 32 зарегистрированных функции, хотя большинство реализаций поддерживают гораздо больше. Более важный, в большинстве реализаций он вообще не работает со способностью удалять [динамические общие объекты] из образа работающей программы, вызываяdlclose
до завершения программы.API, указанный ниже, предназначен для обеспечения соответствия стандарту лечения во время нормального завершения программы, которое включает в себя выполнение
atexit
зарегистрированные функции в правильной последовательности относительно деструкторов, зарегистрированных конструктором, и разумное обращение во время ранней разгрузки DSO (например,dlclose
).
Так:
__cxa_atexit()
не ограничено 32 функциями.__cxa_atexit()
вызовет деструктор статики динамической библиотеки, когда эта динамическая библиотека выгружается до выхода из программы.Вы должен включить -fuse-cxa-atexit
если вы пишете библиотеку, и ваша библиотека имеет эту функцию (например, glibc, musl). На самом деле, в gcc, поставляемом с вашим дистрибутивом, этот флаг уже может быть включен автоматически (будет ошибка компоновщика, если вы включите этот флаг, а libc не будет его поддерживать).
Обратите внимание, что пользователи не должны звонить __cxa_atexit
непосредственно: принимает аргументы, которые должен знать только компилятор / компоновщик ( __dso_handle
).
… Нет пользовательского интерфейса для
__cxa_atexit
поддерживается, поэтому пользователь не может зарегистрироватьatexit
функция с параметром или домашний DSO.
MSVC видимо не использует atexit()
подобные функции запустить глобальные деструкторы. И согласно Деструктор глобальной статической переменной в разделяемой библиотеке не вызывается на dlclose MSVC уже запускает деструкторы на dlclose()
,
Других решений пока нет …