Различные способы выхода из процесса на С++

Существуют различные способы выхода из процесса:

например: ExitProcess, ExitThread (из основного потока), выход, прерывание, возврат из main, завершение.

Я хотел бы знать эффекты, которые каждый метод имеет для статического/глобального/автоматического уничтожения объектов.

Например, у меня есть проект, который сбой (возможно, из-за некоторой ошибки удаления) при вызове ExitProcess, но не при вызове exit(). (связанный с этим вопросом, кстати).

Итак, в основном я хотел бы знать, при каких обстоятельствах происходит освобождение вышеупомянутых объектов и в каком порядке (для VС++).

Ответ 1

Вкратце: Единственное абсолютно безопасное решение - разрешить main() или вашу функцию потока <<21 > .

Стандарт С++ гарантирует (3.6.3/1, 18.3), что деструкторы для глобальных объектов (включая статические объекты) будут вызываться, если вызывается exit(), однако он явно заявляет, что деструкторы для локальных переменных не будут вызываться в Это дело. exit() вызовет любые функции, зарегистрированные с помощью atexit(), а также закроет и закроет любые открытые потоки stdio (включая не менее stdin, stdout, stderr).

Вызов abort() гарантированно не будет вызывать локальные или глобальные деструкторы. Также он не будет вызывать функции, зарегистрированные в потоках atexit() или flush stdio.

Вызов любого примитива Win32, такого как ExitProcess() или ExitThread(), безусловно, не вызовет деструкторы для локальных переменных и почти наверняка не вызовет каких-либо деструкторов для глобальных объектов или любых функций, зарегистрированных в atexit(). Вызов этих функций непосредственно в программе на С++ не рекомендуется - в основном эти функции Win32 и библиотека времени выполнения С++ ничего не знают друг о друге. Фактически даже документация MSDN для ExitThread() рекомендует, чтобы программы на С++ возвращались из функции потока вместо вызова ExitThread().

(Теоретически возможно, что библиотека времени выполнения специально организовала для ExitProcess() вызов глобальных объектов-деструкторов - это можно было бы сделать, всегда загружая определенную DLL, чья функция точки входа будет выполнять эти вызовы, так как ExitProcess() будет вызовите функцию точки входа для каждой загруженной DLL с помощью DLL_PROCESS_DETACH - насколько мне известно, реализация не делает этого.)

Ответ 2

Смотрите исходный код ExitProcess() (опубликовано на compuserve, usenet)