Есть ли необходимость явно сбрасывать выходные потоки перед вызовом abort()
избежать потери продукции?
Как я понимаю, с stderr
там нет буферизации, поэтому звонит abort
после вывода в stderr
/cerr
должно быть хорошо. Как насчет stdout
/cout
или файлы, которые я открываю?
PS. Я работаю в среде Linux (если это имеет значение).
Да, это необходимо, но нет, это может быть невозможно. Если вы прерываете из контекста асинхронного сигнала, вызов 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
Stdout буферизуется, как и файл, который вы открываете с помощью ofstream, например. Вы должны явно очистить их, используя манипулятор сброса