Что должна возвращать функция printf() в случае ошибки?
Читаю ман по printf(): "В случае успеха, возвращается количество напечатанных байт. В случае ошибки возвращается отрицательное значение.".
Ок, хорошо. Есть такой код:
#include <stdio.h>
#include <unistd.h>
int main( int argc, char* argv[], char* envp[] ){
int res;
close( 1 );
res = printf( "0_0\n" );
perror( "printf" );
dprintf( 2, "code is %i\n", res );
return 0;
}
В коде я закрываю stdout и вызываю printf(), которая должна вернуть -1... ну в теории. Запускаем и видим:
$ ./main
printf: Bad file descriptor
code is 4
Это как так-то? Функция явно завершилась с ошибкой, но вернула при этом число байт.
Система линукс, компилятор gcc.
Ответы (1 шт):
printf заимствует часть требований от fprintf, в т.ч. чтобы stdout указывал на файловый поток. Ломая stdout (причем именно ломая, так как закрывается он посредством fclose, а закрытие нижележащего файлового дескриптора переводит поток в неконсистентное состояние), вы нарушаете требования к входящим параметрам для вызова printf и получаете Неопределенное Поведение.
Как продолжение, было бы интересно узнать, когда же printf может все-таки возвратить ошибку при корректном вызове? По идее, такой сценарий можно устроить, если например запустить этот процесс как дочерний, передав ему в качестве дескриптора stdout вход от pipe, и затем закрыв выход в родительском процессе.