703

Many C++ books contain example code like this...

std::cout << "Test line" << std::endl;

...so I've always done that too. But I've seen a lot of code from working developers like this instead:

std::cout << "Test line\n";

Is there a technical reason to prefer one over the other, or is it just a matter of coding style?

General Grievance
  • 4,555
  • 31
  • 31
  • 45
Head Geek
  • 38,128
  • 22
  • 77
  • 87
  • 32
    @derobert this one is older than the other – Kira Nov 13 '13 at 15:31
  • 8
    @HediNaily indeed it is. But the answer on the other one strikes me as slightly better, so I picked to do it that way around. Also, the other one is slightly broader, also covering `'\n'`. – derobert Nov 13 '13 at 15:35
  • 15
    Good explanation: http://cppkid.wordpress.com/2008/08/27/why-i-prefer-n-to-stdendl/ –  Oct 17 '08 at 21:28
  • https://stackoverflow.com/a/30968225/3163618 there may be a significant performance difference. – qwr Mar 24 '20 at 04:38
  • If you intend to run your program on anything else than your own laptop, never ever use the `endl` statement. Especially if you are writing a lot of short lines or as I have often seen single characters to a file. The use of `endl` is know to kill networked file systems like NFS. – John Damm Sørensen Oct 27 '18 at 23:32

11 Answers11

566

The varying line-ending characters don't matter, assuming the file is open in text mode, which is what you get unless you ask for binary. The compiled program will write out the correct thing for the system compiled for.

The only difference is that std::endl flushes the output buffer, and '\n' doesn't. If you don't want the buffer flushed frequently, use '\n'. If you do (for example, if you want to get all the output, and the program is unstable), use std::endl.

Uli Köhler
  • 13,012
  • 16
  • 70
  • 120
David Thornley
  • 56,304
  • 9
  • 91
  • 158
  • 35
    Or consider using `::std::cerr` instead of `::std::cout` since it's unbuffered and flushed with each and every output operation. – Omnifarious Jan 23 '10 at 11:45
  • 181
    @Omnifarious: No std::cerr should be reserved for errors. The two streams are not synced together so if you output some text to cout it may be buffered and the cerr will go direct to the output this resulting in a mixed mode display. Use cerr for what it is supposed to be for (errors) and cout for what it is designed for (normal interaction). – Martin York Feb 03 '10 at 16:39
  • 8
    @Martin York, I agree, that's what `::std::cerr` is for. But, in my opinion, if you have code where you don't want buffering it's much more likely that your output belongs in `::std::cerr`. I can't think of any good reason to routinely forgo buffering for `::std::cout`. – Omnifarious Feb 04 '10 at 01:29
  • std::endl is platform aware too , No? – Lucas Feb 17 '10 at 01:32
  • 26
    @Lucas: No more than '\n' is platform aware. – CB Bailey Feb 17 '10 at 07:39
  • 37
    @LokiAstari: I wouldn't say `stderr` is for "errors". Rather, it's for out-of-band diagnostic messages, if you will. It should be possible to say `./prog > file` and store only the true program payload, but the program may like to output a lot more status information, even in normal interaction. – Kerrek SB Nov 28 '11 at 03:01
  • 19
    "In many implementations, standard output is line-buffered, and writing '\n' causes a flush anyway, unless std::cout.sync_with_stdio(false) was executed." [copied from here](http://en.cppreference.com/w/cpp/io/manip/endl) – GuLearn Aug 13 '13 at 21:01
  • 11
    @Omnifarious please don't put all your output in `cerr`. Printing only errors to cerr allows you to then separate the two output streams by redirecting them to different places. If I redirect `cerr` output with `2>/dev/null` I don't want to have all my regular output disappear too. Likewise, if I redirect all my regular output to a file like `1>output.txt` I want all of my output and no errors to be there. Or if I pipe it to `grep` or `more`, I want the pipe to push over `cout` stuff, as expected, and to then pipe errors by doing `3>&1 1>&2 2>&3 | grep` So please, please don't mix them. Ever. – Cory-G Jul 01 '14 at 15:36
  • @Omnifarious: A good reason to routinely forego buffering is that you want your output to be available when written rather than at some indeterminate time in the future. But usually you want buffering to happen while you're in the process of writing a chunk of output. –  Sep 15 '15 at 16:42
  • There's also [ostream::flush](http://www.cplusplus.com/reference/ostream/ostream/flush/) – Braden Best Sep 26 '16 at 23:15
  • 1
    '\n' will also flush if the output is connected to an interactive device, like a terminal. – Emily L. Jan 18 '18 at 14:16
  • 1
    I see many people say "flush" - but all that ostream::flush does is call sync() on the underlaying streambuf, so it totally depends on the streambuf implementation what happens. For example a fstream uses a filebuf, so the effect is https://en.cppreference.com/w/cpp/io/basic_filebuf/sync ; Also calling https://en.cppreference.com/w/cpp/io/ios_base/sync_with_stdio or not seems rather important and nobody (except GuLearn) even mentions it :/ – Carlo Wood Feb 27 '19 at 10:36
  • Note stdout is only line buffered if it is considered to be interactive, it is fully buffered if non-interactive - see https://stackoverflow.com/questions/5229096/does-printf-always-flush-the-buffer-on-encountering-a-newline. – studgeek Jan 25 '21 at 01:51
304

The difference can be illustrated by the following:

std::cout << std::endl;

is equivalent to

std::cout << '\n' << std::flush;

So,

  • Use std::endl If you want to force an immediate flush to the output.
  • Use \n if you are worried about performance (which is probably not the case if you are using the << operator).

I use \n on most lines.
Then use std::endl at the end of a paragraph (but that is just a habit and not usually necessary).

Contrary to other claims, the \n character is mapped to the correct platform end of line sequence only if the stream is going to a file (std::cin and std::cout being special but still files (or file-like)).

sabbahillel
  • 4,357
  • 1
  • 19
  • 36
Martin York
  • 257,169
  • 86
  • 333
  • 562
  • 6
    In many cases, the "see the output immediately" is a red herring, since `cout` is tied to `cin`, meaning that if you read input from `cin`, `cout` will be flushed first. But if you want to display a progress bar or something without reading from `cin`, then sure, flushing is useful. – C. K. Young Mar 30 '11 at 05:55
  • 20
    @LokiAstari: _if you are using the << operator, you probably aren't worried about performance_ - why? I didn't know that `operator<<` isn't performant, or what alternative to use for performance? Please point me to some material to understand this further. – legends2k Jan 22 '14 at 07:33
  • 19
    @legends2k: There is an old wives tale that C++ streams are not as performant as C printf(). Though true to an extent the main difference in speed is caused by people using C++ streams incorrectly. http://stackoverflow.com/a/1042121/14065 In C++ remember to unsync iostreams with C-streams `sync_with_stdio(false)` and don't flush your output continuously. Let the library work out when to do it. http://stackoverflow.com/a/1926432/14065 – Martin York Jan 22 '14 at 19:53
  • 7
    @Loki: There's an urban legend that `sync_with_stdio` makes iostreams as fast as stdio. [It does not](http://stackoverflow.com/q/4340396/103167) – Ben Voigt Sep 15 '15 at 16:30
  • 5
    @BenVoigt: I was careful with my wording above (so I am happy with them). It is not as performant as stdio (because it does more). **BUT** a lot of the performance gap people complain about is cause by sync with stdio. – Martin York Sep 15 '15 at 20:43
  • 1
    What's the point to use `std::endl` if `\n` is more efficient in 99% of cases ? – Tesla123 Mar 01 '23 at 18:37
  • @Tesla123 It forces a flush (which has it uses). But I rarely use `std::endl`. Like all tools use as is appropriate. – Martin York Mar 02 '23 at 00:08
49

There might be performance issues, std::endl forces a flush of the output stream.

Richard
  • 56,349
  • 34
  • 180
  • 251
Martin Beckett
  • 94,801
  • 28
  • 188
  • 263
39

There's another function call implied in there if you're going to use std::endl

a) std::cout << "Hello\n";
b) std::cout << "Hello" << std::endl;

a) calls operator << once.
b) calls operator << twice.

roottraveller
  • 7,942
  • 7
  • 60
  • 65
Nathan
  • 407
  • 4
  • 2
  • 33
    It may be obvious, but it has a huge impact on threaded programs where, generally, the first version will write a single line in one shot where the second version may be split by writes from other threads. Often enough I find myself writing std::cout << "hello\n" << std::flush to avoid this. – smparkes Jun 22 '11 at 23:15
  • What about `std::cout << "Hello" << "\n";`? – byxor Feb 22 '18 at 20:39
  • 1
    @byxor Almost the same except the buffer flushing as described in other answers. Anyway, it's redundant when you can merge the two string literals into one. – iBug Apr 19 '18 at 06:44
  • Well, if the string to be printed is not a literal, then the calls to the `<<` would be 2 in the case _a_ as well, thus I wouldn't claim the need for one or two `<<` (or two function calls in general) be a difference between `\n` and `endl`. – Enlico Nov 22 '18 at 14:30
  • Lol no, that is not the reason I use \n. – Carlo Wood Feb 27 '19 at 10:27
35

I recalled reading about this in the standard, so here goes:

See C11 standard which defines how the standard streams behave, as C++ programs interface the CRT, the C11 standard should govern the flushing policy here.

ISO/IEC 9899:201x

7.21.3 §7

At program startup, three text streams are predefined and need not be opened explicitly — standard input (for reading conventional input), standard output (for writing conventional output), and standard error (for writing diagnostic output). As initially opened, the standard error stream is not fully buffered; the standard input and standard output streams are fully buffered if and only if the stream can be determined not to refer to an interactive device.

7.21.3 §3

When a stream is unbuffered, characters are intended to appear from the source or at the destination as soon as possible. Otherwise characters may be accumulated and transmitted to or from the host environment as a block. When a stream is fully buffered, characters are intended to be transmitted to or from the host environment as a block when a buffer is filled. When a stream is line buffered, characters are intended to be transmitted to or from the host environment as a block when a new-line character is encountered. Furthermore, characters are intended to be transmitted as a block to the host environment when a buffer is filled, when input is requested on an unbuffered stream, or when input is requested on a line buffered stream that requires the transmission of characters from the host environment. Support for these characteristics is implementation-defined, and may be affected via the setbuf and setvbuf functions.

This means that std::cout and std::cin are fully buffered if and only if they are referring to a non-interactive device. In other words, if stdout is attached to a terminal then there is no difference in behavior.

However, if std::cout.sync_with_stdio(false) is called, then '\n' will not cause a flush even to interactive devices. Otherwise '\n' is equivalent to std::endl unless piping to files: c++ ref on std::endl.

Emily L.
  • 5,673
  • 2
  • 40
  • 60
23

They will both write the appropriate end-of-line character(s). In addition to that endl will cause the buffer to be committed. You usually don't want to use endl when doing file I/O because the unnecessary commits can impact performance.

Ferruccio
  • 98,941
  • 38
  • 226
  • 299
16

Not a big deal, but endl won't work in boost::lambda.

(cout<<_1<<endl)(3); //error

(cout<<_1<<"\n")(3); //OK , prints 3
Özgür
  • 8,077
  • 2
  • 68
  • 66
14

If you use Qt and endl, you could accidentally end up using an incorrect endl which gives you very surprising results. See the following code snippet:

#include <iostream>
#include <QtCore/QtCore> 
#include <QtGui/QtGui>

// notice that there is no "using namespace std;"
int main(int argc, char** argv)
{
    QApplication qapp(argc,argv);
    QMainWindow mw;
    mw.show();
    std::cout << "Finished Execution!" << endl;
    // This prints something similar to: "Finished Execution!67006AB4"
    return qapp.exec();
}

Note that I wrote endl instead of std::endl (which would have been correct) and apparently there is a endl function defined in qtextstream.h (which is part of QtCore).

Using "\n" instead of endl completely sidesteps any potential namespace issues. This is also a good example why putting symbols into the global namespace (like Qt does by default) is a bad idea.

smerlin
  • 6,446
  • 3
  • 35
  • 58
10

Something that I've never seen anyone say is that '\n' is affected by cout formatting:

#include <iostream>
#include <iomanip>

int main() {
    std::cout << "\\n:\n" <<  std::setw(2) << std::setfill('0') << '\n';
    std::cout << "std::endl:\n" << std::setw(2) << std::setfill('0') << std::endl;
}

Output:

\n:
0
std::endl:

Notice, how since '\n' is one character and fill width is set to 2, only 1 zero gets printed before '\n'.

I can't find anything about it anywhere, but it reproduces with clang, gcc and msvc.

I was super confused when I first saw it.

TheHardew
  • 399
  • 4
  • 12
  • This is due to Windows level implementation, where \n is just the line feed character, while endl is both the carriage return (\r) and line feed (\n) for a total of \r\n. Like others pointed out, \n should actually give \r\n if the stream is going to a file. – leoleosuper May 05 '22 at 07:40
  • @leoleosuper this behaves the same way on linux with `cout`/`ofstream` (I have not tested `ofstream` on windows). Neither `endl` nor `\n` produce the carriage return when passed through `xxd` on linux. Did you reply to a wrong answer? You say "Like others pointed out", but you are the only comment here. – TheHardew May 05 '22 at 15:26
  • I mean other answers/comments on those answers pointed that out. I think I figured it out: putting '\n' goes through cout, and as such, setfill will fill the character before. endl does not go through cout to place the character, instead placing it directly, and then flushing the output. So with your set up, cout << '\n' will modify the input string to "0\n", then use os.put("0\n") in order to put the 0 and newline. endl, on the other hand, goes directly to os.put('\n'), ignoring the setfill. – leoleosuper May 08 '22 at 23:50
  • 1
    @leoleosuper It is not `endl` that is platform dependent. Formatted output of '\n' is the thing that is platform dependent. On Windows formatted output of '\n' will give the carriage return too. I suspect that on Windows the output will not show a 0. What is interesting is what it would do on Windows if the width is set to 1. – Troubadour Apr 10 '23 at 11:43
8

With reference This is an output-only I/O manipulator.

std::endl Inserts a newline character into the output sequence os and flushes it as if by calling os.put(os.widen('\n')) followed by os.flush().

When to use:

This manipulator may be used to produce a line of output immediately,

e.g.

when displaying output from a long-running process, logging activity of multiple threads or logging activity of a program that may crash unexpectedly.

Also

An explicit flush of std::cout is also necessary before a call to std::system, if the spawned process performs any screen I/O. In most other usual interactive I/O scenarios, std::endl is redundant when used with std::cout because any input from std::cin, output to std::cerr, or program termination forces a call to std::cout.flush(). Use of std::endl in place of '\n', encouraged by some sources, may significantly degrade output performance.

Kaleem Ullah
  • 6,799
  • 3
  • 42
  • 47
0

From GCC docs:

Some people also believe that sending endl down an output stream only writes a newline. This is incorrect; after a newline is written, the buffer is also flushed. Perhaps this is the effect you want when writing to a screen -- get the text out as soon as possible, etc -- but the buffering is largely wasted when doing this to a file:

output << "a line of text" << endl;
output << some_data_variable << endl;
output << "another line of text" << endl; 

The proper thing to do in this case to just write the data out and let the libraries and the system worry about the buffering. If you need a newline, just write a newline:

output << "a line of text\n"
<< some_data_variable << '\n'
<< "another line of text\n"; 

You can check the docs for ostream, or check endl implementation itself - on my case at usr/include/c++/11/ostream:684 -. There you are going to find:

  // Standard basic_ostream manipulators

  /**
   *  @brief  Write a newline and flush the stream.
   *
   *  This manipulator is often mistakenly used when a simple newline is
   *  desired, leading to poor buffering performance.  See
   *  https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html#io.streambuf.buffering
   *  for more on this subject.
  */
  template<typename _CharT, typename _Traits>
    inline basic_ostream<_CharT, _Traits>&
    endl(basic_ostream<_CharT, _Traits>& __os)
    { return flush(__os.put(__os.widen('\n'))); }
jonathask
  • 115
  • 1
  • 6