Является ли это корректным поведением для выхода из программы до основного?

Определенно можно выполнить код до вызова main, как видно из многих примеров в этом вопросе.

Однако, что, если в этом предварительном главном коде программе предлагается выйти через std::exit или std::abort? Поскольку main определяется как начало программы, каковы последствия от выхода до начала?

После печати в каждом разделе я получаю следующие результаты:

Формат:
Раздел: output

Главная: main
Инициализировать (вызывается перед основным): init
Выход (настроено с std::atexit внутри Init): exiting



Примеры прогона:

Инициировать вызов без выхода:

INIT
основной
возвращает 0

Инициирует вызовы std:: exit (0):

INIT
возвращает 0

Инициирует вызовы std:: abort:

INIT
сбой и возврат 3 в Windows с помощью GCC 4.7.2
сбой и вызывает обычную коробку с VS11
возвращает 0 в LiveWorkSpace

Init устанавливает обработчик и вызывает std:: exit (0):

INIT
выход
возвращает 0

Init устанавливает обработчик и вызывает std:: abort:

INIT
то же дело, что и без обработчика

Во время поиска я увидел этот вопрос: Есть ли способ, с помощью которого программа C/С++ может сбой перед main()?. Тем не менее, он не отвечает на то, что я хочу знать. Является ли какое-либо из этого поведения, вызывающим std::exit или std::abort до main, четко определенным? Является ли какое-либо из этого поведения undefined?

Ответ 1

Короткий ответ: есть (почти) никаких последствий. Некоторые деструкторы не могут быть вызваны, если вы неожиданно вызываете exit, но это в значительной степени оно. Как правило, не вызов деструкторов не самый чистый способ, но тогда конечный результат будет таким же.

Когда процесс завершается (через exit или abort или просто путем segfaulting или по другой причине), дескрипторы (объекты ядра, файлы и т.д.) закрываются, а память, связанная с адресным пространством программы, восстанавливается операционной системой.

С ним еще не так много, потому что, когда вы вызываете exit или abort, вы в основном запрашиваете, что программа завершается (эти функции никогда не возвращаются!), поэтому вы действительно не можете ожидать, что что-то произойдет в дальнейшем.

Обратите внимание, что регистрация функции типа Init, которая должна быть вызвана до main, является нестандартной, но вы можете получить тот же эффект, если иметь конструктор в глобальном.