Diamo uno sguardo a questo programma Ciao MondoDifferenza tra FILE * "/ dev/stdout" e stdout
#include <stdio.h>
int main(int argc, char ** argv) {
printf("Hello, World!");
const char* sFile = "/dev/stdout"; // or /proc/self/fd/0
const char* sMode = "w";
FILE * output = fopen(sFile, sMode);
//fflush(stdout) /* forces `correct` order */
putc('!', output); // Use output or stdout from stdio.h
return 0;
}
Quando compilato utilizzando il descrittore output
file l'output è:
!Hello, World!
quando viene compilato utilizzando il descrittore di file stdout
fornito da stdio.h
l'output è come previsto:
Hello, World!!
Immagino che quando si chiama putc
con quest'ultimo, stamperà direttamente al stdout
e quando si utilizza il descrittore di file su /dev/stdout
si aprirà una pipe e stampare in quello. Non sono sicuro però.
Il comportamento è ancora più interessante, in quanto non sovrascrive il primo carattere di "Hello", ma si spinge piuttosto nella prima posizione del buffer di riga di fronte alla stringa già premuta.
Da un punto di vista logico questo è silenzioso inaspettato.
Qualcuno può spiegare cosa sta succedendo esattamente qui?
sto usando cc (Ubuntu 4.8.2-19ubuntu1) 4.8.2
e un kernel linux 3.13.0-52 compilato w/gcc 4.8.2
Edit: Ho fatto un strace
di entrambi i programmi, e qui è la parte importante:
il output
(fopen ("/ dev/stdout", "w")) senza fflush(stdout)
scenar io produce:
...
open("/dev/stdout", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
fstat(3, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f62f21e9000
write(3, "!", 1!) = 1
write(1, "Hello, World!", 13Hello, World!) = 13
exit_group(0) = ?
utilizzando fflush(stdout)
produce e impone ordine corretto:
...
open("/dev/stdout", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
write(1, "Hello, World!", 13Hello, World!) = 13
fstat(3, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5ad4557000
write(3, "!", 1!) = 1
exit_group(0) = ?
Il stdout
(da stdlib.h) scenario produce:
...
write(1, "Hello, World!!", 14Hello, World!!) = 14
exit_group(0) = ?
così sembra la FILE * output = fopen("/dev/stdout")
stream utilizza un descrittore di file diverso da stdout
Anche come sembra che printf
usi stdout
Quindi nel terzo scenario la stringa viene assemblata prima di essere spinta nello stream.
'stdout' è un FILE *, non un descrittore di file. Allo stesso modo, 'output' non è un descrittore di file. Ognuno ha un descrittore di file sottostante e se si dovesse scrivere direttamente ad esso non si vedrebbe questo comportamento. (Scrittura diretta sul descrittore di file ignora il buffering.) –
La grande differenza è che ogni "FILE *" utilizza il proprio buffer, non correlato tra loro. –