Существует разница между FILE *
s stdout и stderr и файловыми дескрипторами 1 и 2. В этом случае именно ФАЙЛЫ вызывают поведение, которого вы не ожидали. stderr
не буферизируется по умолчанию, поэтому в случае ошибки вы можете распечатать сообщение наиболее надежным способом, даже если производительность этой печати замедляет общую производительность программы.
stdout
, по умолчанию, буферизуется. Это означает, что у него есть массив памяти, в котором хранятся данные, которые вы сказали ему записать. Он ожидает, пока массив (называемый буфером) не будет заполнен до определенного уровня или (если он настроен для буферизации строк, что это часто), пока не увидит '\n'
. Вы можете позвонить по номеру fflush(stdout);
и напечатать.
Вы можете изменить настройки буферизации FILE *
. man 3 setbuf
имеет функции, которые делают это для вас.
В вашем примере буфер stdout
содержал строку "stdout", в то время как "stderr" записывался на экран. Затем при выходе из программы все открытые FILE *
сбрасываются, поэтому выводится «stdout».