C / C ++: очистить вывод перед аварийным завершением

Есть ли необходимость явно сбрасывать выходные потоки перед вызовом abort() избежать потери продукции?

Как я понимаю, с stderr там нет буферизации, поэтому звонит abort после вывода в stderr/cerr должно быть хорошо. Как насчет stdout/coutили файлы, которые я открываю?

PS. Я работаю в среде Linux (если это имеет значение).

2

Решение

Да, это необходимо, но нет, это может быть невозможно. Если вы прерываете из контекста асинхронного сигнала, вызов fflush вызывает неопределенное поведение. И вообще, если причина звонка abort является то, что вы обнаружили несогласованное состояние в вашей программе, есть риск, что состояние stdio также повреждено, и что вызов fflush Поэтому небезопасно.

В общем, вы должны использовать exit(1) если вы завершаете работу из-за условия, которое ваша программа просто не может обработать, и использовать abort() (без fflush) только когда вы обнаружили, что ваша программа уже вызывала неопределенное поведение,

Еще несколько деталей:

Стандарт С позволяет реализация для очистки потоков stdio как часть прерывания (C11 7.22.4.1 :):

Сбрасываются ли открытые потоки с неписанными буферизованными данными, закрытые потоки или удаляются временные файлы, определяется реализацией.

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

Текущая версия справочной страницы Linux для abort неправильно заявляет:

Если функция abort () вызывает завершение процесса, все открытые потоки закрываются и очищаются.

Более правильным утверждением текущего поведения будет то, что сброс попытка но может дать сбой или испортить ваши данные. Эта ошибка в настоящее время находится в процессе исправления в glibc (может быть, исправление уже было зафиксировано …?) В соответствии с этой веткой:

http://www.sourceware.org/ml/libc-alpha/2013-05/msg00207.html

9

Другие решения

Stdout буферизуется, как и файл, который вы открываете с помощью ofstream, например. Вы должны явно очистить их, используя манипулятор сброса

0