IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

std::endl vs '\n'


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 288
    Billets dans le blog
    2
    Par défaut std::endl vs '\n'
    Citation Envoyé par grim7reaper Voir le message
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include <iostream>
     
    int main()
    {
        int a, b;
     
        std::cout << "Saisir deux nombres\n";
        std::cin >> a >> b;
        std::swap(a, b);
        std::cout << a << ' ' << b << '\n';
     
        return 0;
    }
    <mode:chipotage>
    Préférer l'utilisation de std::endl à la place du '\n'.
    </mode>

  2. #2
    Membre chevronné
    Inscrit en
    Juillet 2012
    Messages
    231
    Détails du profil
    Informations forums :
    Inscription : Juillet 2012
    Messages : 231
    Par défaut
    Citation Envoyé par r0d Voir le message
    <mode:chipotage>
    Préférer l'utilisation de std::endl à la place du '\n'.
    </mode>
    Au contraire, j’ai utilisé \n parce que je voulais éviter std::endl. Ici je veux juste faire un retour à la ligne, ni plus ni moins, donc \n est parfaitement adapté.
    Sur stdout, en général std::endl et \n ont le même effet (vu que, par défaut, stdout est souvent bufferisé par ligne) donc oui c’est vraiment une histoire de préférence personnelle que d’utiliser l’un ou l’autre.
    En revanche, sur un fichier on risque de sentir une différence (flusher le buffer à chaque ligne c’est pas terrible niveau perf’ )

  3. #3
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 288
    Billets dans le blog
    2
    Par défaut
    Ma remarque était dans le cadre d'une réponse à une question de débutant. Les deux méthodes étant à peu près identiques, il est conseillé d'utiliser la méthode la plus standard, à savoir celle qui utilise la lib standard du c++.

    Citation Envoyé par grim7reaper Voir le message
    En revanche, sur un fichier on risque de sentir une différence (flusher le buffer à chaque ligne c’est pas terrible niveau perf’ )
    ça dépend le but recherché. Si tu veux faire un logger ou n'importe quel type d'output que tu souhaites pouvoir vérifier en temps réel, alors tu n'as pas le choix. Et de façon générale, ne pas flusher systématiquement pose de nombreux problèmes de robustesse: il est difficile de contrôler le chemin d'exécution si on ne sait pas où ça flushe. Et il y a le problème du multithreading.
    D'une façon générale, il faut préférer le endl. Et si jamais cela pose des problèmes de performance au runtime, alors la question de remplacer par des '\n' pourra se poser, mais seulement après.

  4. #4
    Membre chevronné
    Inscrit en
    Juillet 2012
    Messages
    231
    Détails du profil
    Informations forums :
    Inscription : Juillet 2012
    Messages : 231
    Par défaut
    Citation Envoyé par r0d Voir le message
    Les deux méthodes étant à peu près identiques, il est conseillé d'utiliser la méthode la plus standard, à savoir celle qui utilise la lib standard du c++.
    '\n' c’est autant du C++ standard que std::endl
    Par contre, les deux ont des sémantiques différentes oui : l’un est le moyen standard de faire un retour à la ligne, l’autre est le moyen standard de faire un retour à la ligne + flush.

    Citation Envoyé par r0d Voir le message
    ça dépend le but recherché. Si tu veux faire un logger ou n'importe quel type d'output que tu souhaites pouvoir vérifier en temps réel, alors tu n'as pas le choix.
    Oui, tout à fait.
    Dans ce cas-là c’est pleinement justifié.

    Citation Envoyé par r0d Voir le message
    Et de façon générale, ne pas flusher systématiquement pose de nombreux problèmes de robustesse: il est difficile de contrôler le chemin d'exécution si on ne sait pas où ça flushe.
    Rien n’empêche de faire des appels à std::flush à des « points de contrôle ». Comme ça tu sais exactement où ça flushe.
    Après tout dépend de l’application (oui un logger doit flusher à chaque ligne donc std::endl est parfait), mais il peut aussi y avoir un juste milieu entre ne jamais flusher (laisser le système gérer) et flusher à chaque ligne.

    Citation Envoyé par r0d Voir le message
    Et il y a le problème du multithreading.
    Hum, en général si tu as plusieurs threads qui veulent écrirent en même temps sur le même flux tu vas protéger l’accès par un mutex, flush ou pas.
    Le flush ne va pas te protéger de l’entrelacement pour ce que j’en sais.

    Citation Envoyé par r0d Voir le message
    D'une façon générale, il faut préférer le endl. Et si jamais cela pose des problèmes de performance au runtime, alors la question de remplacer par des '\n' pourra se poser, mais seulement après.
    Personnellement, j’ai plutôt l’approche inverse.
    Par défaut, on va au plus simple : simple retour à la ligne.
    Après, si besoin il y a ou cas particulier (le logger était un très bon exemple), on ajoute des flush (ou usage de std::endl).

    Mais, ça reste un détail.

  5. #5
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 288
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par grim7reaper Voir le message
    '\n' c’est autant du C++ standard que std::endl
    Non, endl prend en compte les différences entre système d'exploitation, les encodages, etc. Par exemple, dans certains encodages, un retour charriot d'un fichier est '\r\n'. endl gère tout ça.

    Citation Envoyé par grim7reaper Voir le message
    Rien n’empêche de faire des appels à std::flush à des « points de contrôle ». Comme ça tu sais exactement où ça flushe.
    Après tout dépend de l’application (oui un logger doit flusher à chaque ligne donc std::endl est parfait), mais il peut aussi y avoir un juste milieu entre ne jamais flusher (laisser le système gérer) et flusher à chaque ligne.

    Hum, en général si tu as plusieurs threads qui veulent écrirent en même temps sur le même flux tu vas protéger l’accès par un mutex, flush ou pas.
    Le flush ne va pas te protéger de l’entrelacement pour ce que j’en sais.
    En gros, pourquoi faire simple quand on peut faire compliqué?
    Pour le MT, utiliser endl te permet au moins de ne protéger que tes accès en écriture. Si tu utilises '\n', il faut que tu gère les accès concurrents à tous les niveaux, ça peut vite devenir ingérable.

    Citation Envoyé par grim7reaper Voir le message
    Par défaut, on va au plus simple : simple retour à la ligne.
    Sauf que le plus simple c'est le endl, c'est pas le '\n'. De même que le plus simple c'est la classe string, pas le char*.

    Citation Envoyé par grim7reaper Voir le message
    Mais, ça reste un détail.
    C'est un détail, mais si cette discussion revient régulièrement c'est parce qu'elle cristallise deux visions du c++. Une vision qui conçoit le c++ en tant qu'amélioration du C, et une autre vision, qui est la mienne, qui prend le c++ comme un langage à part entière, et dont la stl est la brique de base, dont il faut abuser.

  6. #6
    Membre chevronné
    Inscrit en
    Juillet 2012
    Messages
    231
    Détails du profil
    Informations forums :
    Inscription : Juillet 2012
    Messages : 231
    Par défaut
    Citation Envoyé par r0d Voir le message
    Non, endl prend en compte les différences entre système d'exploitation, les encodages, etc. Par exemple, dans certains encodages, un retour charriot d'un fichier est '\r\n'. endl gère tout ça.
    Ça c’est un mythe. \n a exactement le même effet au niveau de l’encodage de la fin de ligne. C’est tout aussi portable.
    Et tu sais pourquoi ?
    Parce std::endl ne fait rien de plus que d’écrire \n dans le flux puis il appelle std::flush. Il y a bien un appel à os.widen mais ça n’a rien à voire avec les histoire de \n, \r ou \r\n…
    Je t’invite à faire le test (ou à lire la section 27.7.3.8 du standard).

    Citation Envoyé par r0d
    En gros, pourquoi faire simple quand on peut faire compliqué?
    Pour le MT, utiliser endl te permet au moins de ne protéger que tes accès en écriture. Si tu utilises '\n', il faut que tu gère les accès concurrents à tous les niveaux, ça peut vite devenir ingérable.
    Là je ne vois pas de quoi tu parles.
    flush ou pas, si deux threads joue en même temps sur le même flux tu risques des soucis.
    Tu peux me donner un exemple s’il te plaît ? Ça sera peut-être plus clair.

    Citation Envoyé par r0d
    Sauf que le plus simple c'est le endl, c'est pas le '\n'. De même que le plus simple c'est la classe string, pas le char*.
    Je suis d‘accord pour std::string vs char*, par contre pas pour std::endl vs \n.
    Pour moi il n’est pas plus simple, il joue un autre rôle.

    Citation Envoyé par r0d
    C'est un détail, mais si cette discussion revient régulièrement c'est parce qu'elle cristallise deux visions du c++. Une vision qui conçoit le c++ en tant qu'amélioration du C, et une autre vision, qui est la mienne, qui prend le c++ comme un langage à part entière, et dont la stl est la brique de base, dont il faut abuser.
    Moi aussi j’ai cette vision et je lutte contre ceux qui font du C-with-classes ou un sabir C/C++.
    Mais là, à t’entendre on dirait que \n ce n’est pas du C++, mais du C. Et je trouve ça un peu fort.
    Moi aussi je suis pour utiliser à fond la STL, quand c’est justifié. Mais je pense aussi que quand \n remplit son rôle autant l’utiliser (surtout qu’il est tout aussi portable que std::endl comme je l’ai montré plus haut).

Discussions similaires

  1. faire comme std::endl
    Par mister3957 dans le forum C++
    Réponses: 4
    Dernier message: 21/01/2010, 14h03
  2. surcharger std::endl ?
    Par ambroise_petitgenet dans le forum SL & STL
    Réponses: 2
    Dernier message: 28/03/2009, 14h47
  3. Surcharge d'opérateur << et std::endl;
    Par Tourix dans le forum SL & STL
    Réponses: 7
    Dernier message: 29/06/2006, 17h58
  4. std::endl c'est quoi ??
    Par elekis dans le forum SL & STL
    Réponses: 8
    Dernier message: 14/09/2005, 17h15
  5. STL : std::set problème avec insert ...
    Par Big K. dans le forum MFC
    Réponses: 13
    Dernier message: 08/11/2003, 01h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo