¿Por qué el orden de salida es diferente del orden de llamada cuando se usa fprintf con stdout o stderr?

Mi entorno es Debian GNU/Linux 11.

La fprintffunción con param stdouto stderrda un orden de salida inesperado.

int main() {
    std::cout << "Hello, World!" << std::endl;
    fprintf(stderr, "22222\n");
    fprintf(stdout, "111\n");
    printf("3333 \n");
    printf("44444 \n");
    return 0;
}

He ejecutado esto muchas veces y obtuve muchos resultados diferentes:

//①
22222
Hello, World!
111
3333 
44444

//②
Hello, World!
111
3333 
44444 
22222

¿Cual es la razón? O, quiero entender el fenómeno, ¿qué conocimientos necesito?

Según tengo entendido, el registro de salida debería ser así:

//③
Hello, World!
22222
111
3333 
44444 

Acerca de los dos registros de salida de ①/②, no entiendo.

Creo que log ③ tiene razón, pero no aparece, eso me hace dudar.

Answer

La salida nunca es como ② porque la salida a stderrno está almacenada en búfer , por lo 22222que se vaciará inmediatamente y estará antes que cualquier otro número. La salida stdoutpuede tener un búfer de línea (predeterminado en Linux) o un búfer completo (predeterminado en Windows)

La salida tampoco debería ser como ① porque ya está descargando std::endlen la primera línea , por lo tanto Hello, World!, se imprimiría primero. Es por eso que nunca lo use std::endla menos que realmente sepa lo que está haciendo. Usa siempre std::cout << "Hello, World!\n";. Ver "std::endl" frente a "\n"

③ debería ser la salida correcta porque en Linux se vaciará en cada declaración, y en Windows las 3 escrituras finales stdoutse vaciarán a la vez al final

Hello, World!
22222
111
3333 
44444

Si hay alguna diferencia, entonces hay algunos problemas con su stdlib

De forma predeterminada , los flujos heredados y C++ también están sincronizados , por lo que es posible mezclar ambos tipos de flujos con alguna penalización en el rendimiento. Puedes desactivarlo así

std::ios::sync_with_stdio(false);

para obtener un mejor rendimiento, pero ahora la Hello, World!cadena se puede imprimir en cualquier lugar