Wann ist endl gut?



  • Hallo,
    ich lese extrem oft, dass man endl nur nehmen soll, wenn man es muss, aber WANN muss man denn überhaupt flushen? Wenn ich z.B. einen Errorlog habe, der sofort den jeweiligen Fehler in die Datei schreiben soll, soll ich dann endl benutzen? Oder wann muss man flushen?



  • Flushen sollst du wenn der Stream gepuffert ist (wie std::clog ) und du den Puffer "leeren" willst. Bei direkten Streams (wie std::cerr ) macht es IM(H)O keinen Sinn.



  • Naja, ein std::stream Flush ist ja kein vollständiger Flush, es flusht sich dabei ja nur der C++ Teil, fsync/FlushFileBuffers wird dabei eh nicht aufgerufen. Von daher nicht SO tragisch.

    Und zumindest cin/cout/clog flushen sich auch brav selbst wenn man \n hineintut - auch ohne std::endl.



  • hustbaer schrieb:

    Naja, ein std::stream Flush ist ja kein vollständiger Flush, es flusht sich dabei ja nur der C++ Teil, fsync/FlushFileBuffers wird dabei eh nicht aufgerufen. Von daher nicht SO tragisch.

    Und zumindest cin/cout/clog flushen sich auch brav selbst wenn man \n hineintut - auch ohne std::endl.

    Zum oberen Teil kann ich nichts sagen, aber dass sich cin und cout bei \n flushen, stimmt nicht. std::endl kann aber durch das verständlichere "\n" << std::flush ersetzt werden. Flushen könnte man z.B. wenn man eine länger laufende Anwendung hat, die ihre Informationen auf std::cout schreibt, damit eine andere Anwendung mitlesen kann. Wenn man dann nicht flusht, muss die andere Anwendung ewig warten, bis sie die Daten lesen kann. Auf der Kommandozeile erscheint die Ausgabe aber auch ohne Flush. (Ist es das, was du mit deinem oberen Satz gemeint hast?)



  • hustbaer schrieb:

    Und zumindest cin/cout/clog flushen sich auch brav selbst wenn man \n hineintut - auch ohne std::endl.

    Nope. Das hat mit dem Ziel Device zu tun. Wenn es Interaktiv ist (Console) dann ja, ansonsten nein.

    Der Standard verlangt kein bestimmtes flushen. Bis auf bei cerr, das ist unbuffered.



  • Shade Of Mine schrieb:

    hustbaer schrieb:

    Und zumindest cin/cout/clog flushen sich auch brav selbst wenn man \n hineintut - auch ohne std::endl.

    Nope. Das hat mit dem Ziel Device zu tun. Wenn es Interaktiv ist (Console) dann ja, ansonsten nein.

    Also ich erinnere mich an keine definierte Vorgabe bezüglich des Ziels und wann und wo die Streams geflusht werden müssen, nur an ios::tie() (und daß cin/cout das per default aktiv haben) und ios::sync_with_stdio() (auch per default aktiv).



  • CStoll schrieb:

    Shade Of Mine schrieb:

    hustbaer schrieb:

    Und zumindest cin/cout/clog flushen sich auch brav selbst wenn man \n hineintut - auch ohne std::endl.

    Nope. Das hat mit dem Ziel Device zu tun. Wenn es Interaktiv ist (Console) dann ja, ansonsten nein.

    Also ich erinnere mich an keine definierte Vorgabe bezüglich des Ziels und wann und wo die Streams geflusht werden müssen, nur an ios::tie() (und daß cin/cout das per default aktiv haben) und ios::sync_with_stdio() (auch per default aktiv).

    Deshalb hab ich ja geschrieben
    > Der Standard verlangt kein bestimmtes flushen. Bis auf bei cerr, das ist unbuffered. <

    Aber in der Praxis ist es so, dass wenn das Ziel ein Interaktives Device wie zB die Konsole ist, dass \n einen Flush bedeutet. Denn sonst sind interaktive Devices einfach nicht sinnvoll nutzbar.



  • Ich würde bei einem interaktiven Device eher davon ausgehen, daß dort das tie()-Verhalten dafür sorgt, daß nichts durcheinandergerät (d.h. der Zugriff auf cin löst als erstes ein cout.flush() aus, bevor er auf Nutzer-Eingaben wartet). Aber ich kann's auch nicht in der Praxis überprüfen.



  • Also in der Praxis ist es so, dass man auf der Console was sieht, sobald man ein \n schickt.
    Ich hatte (fälschlicherweise) angenommen, dass das Standard ist.
    Ich hab' auch mal irgendwo gelesen, dass das so definiert ist, aber dann muss das wohl Falschinformation gewesen sein.



  • CStoll schrieb:

    Der Zugriff auf cin löst als erstes ein cout.flush() aus, bevor er auf Nutzer-Eingaben wartet.

    Ja und genau das steht auch irgendwo im Standard.



  • CStoll schrieb:

    Ich würde bei einem interaktiven Device eher davon ausgehen, daß dort das tie()-Verhalten dafür sorgt, daß nichts durcheinandergerät (d.h. der Zugriff auf cin löst als erstes ein cout.flush() aus, bevor er auf Nutzer-Eingaben wartet). Aber ich kann's auch nicht in der Praxis überprüfen.

    Ja. tie ist wichtig. Aber tie alleine Reicht nicht. Stell dir zB sowas wie ping vor. Wenn da nicht jede Zeile sofort flusht, dann sieht das Ding ziemlich daemlich aus. Alle 5 Sekunden siehst du 5 neue Zeilen 😉 Anstatt jede Sekunde 1.

    Deshalb ist es wichtig dass Interaktive Devices bei \n flushen. Der Standard verlangt natuerlich nichts, er verbietet aber auch nichts. Aber nahezu jede Implementierung wird dieses Verhalten aufweisen - weil es anders einfach fast nie Sinn macht.


Log in to reply