std::endl

M

Michael Mellor

I see so many posts on this newsgroup where people use std::endl but I
can't see why or where they are getting it from. std::endl outputs a new
line and flushes the stream's buffer. It is even 15.7 in the C++ FAQ. In
my quick benchmarking* '\n' outperformed std::endl by over 4 times when
writing to the hard drive and is 5 less characters to type** :).

Are there books out there which tell people to use std::endl? Did
pre-standard C++ not require std::endl to flush the stream?

I hope this rant may stop a couple of people using std::endl except
where it is actually needed because it really annoys me.

Michael Mellor

*g++ 3.3.1 under Cygwin on Windows XP
**Obviously an appropriate using will remove that advantage.
 
J

Jonathan Turkanis

Michael Mellor said:
I see so many posts on this newsgroup where people use std::endl but I
can't see why or where they are getting it from. std::endl outputs a new
line and flushes the stream's buffer. It is even 15.7 in the C++ FAQ. In
my quick benchmarking* '\n' outperformed std::endl by over 4 times when
writing to the hard drive <snip>

How much faster "\n" is than "std::endl" depends critically on what
percentage of character output consists of newlines. Did you compare
the two by writing nothing but newlines, or did you write a sample
text document, such as a web page?
Are there books out there which tell people to use std::endl? Did
pre-standard C++ not require std::endl to flush the stream?

I think I've seen it used in "Hello World!", but I don't recall where.
Stoustrup uses "\n" -- which should come as no surprise.
I hope this rant may stop a couple of people using std::endl except
where it is actually needed because it really annoys me.

Why does it annoy you so much? Most of the posts to this newsgroup are
simple demo programs where performance doesn't matter. Maybe posters
think it's more readable.

Jonathan
 
A

Alf P. Steinbach

I see so many posts on this newsgroup where people use std::endl but I
can't see why or where they are getting it from. std::endl outputs a new
line and flushes the stream's buffer. It is even 15.7 in the C++ FAQ. In
my quick benchmarking* '\n' outperformed std::endl by over 4 times when
writing to the hard drive and is 5 less characters to type** :).

Are there books out there which tell people to use std::endl?

By example, yes.

Did pre-standard C++ not require std::endl to flush the stream?
No.


I hope this rant may stop a couple of people using std::endl except
where it is actually needed because it really annoys me.

That's ill-considered.

std::endl has the virtues of being

* Clear and readable.
* Robust.

"Robust" means that if the app crashes you'll still, hopefully, have the
last line written on disk.

'\n' can be used to _optimize_ output, but good programmers defer such
optimization to when and where it's needed, and then ideally only after
profiling. Especially since it has a cost: lowered readability, less
robustness in the face of crashes or even, in some cases, exceptions.
 
M

Michael Mellor

Alf said:
By example, yes.





That's ill-considered.

std::endl has the virtues of being

* Clear and readable.
* Robust.
I feel its (endl) readability is somewhat arguable, '\n' means a newline
to me and many other programmers, and if not, you could do something like:

static const char newline = '\n';

stream << "text" << newline;

which could be claimed as being even clearer.
"Robust" means that if the app crashes you'll still, hopefully, have the
last line written on disk.
But why have large buffers if you are too worried to use them? When
writing binary data to disk do you explicitly flush between every
record/piece of data?

I dont see code written as:
int a, b;
.....
std::cout << a << std::flush << " " << std::flush << b << std::endl;
because it is inefficient yet it is obviously more robust.


Most C programs I have come across:
printf("a line\n");
printf("another line\n");
.....

and not

printf("a line\n"); fflush(stdout);
printf("another line\n"); fflush(stdout);
.....

Are C++ programmers more paranoid about crashes? perhaps C programmers
should opt for the latter approach.

Michael Mellor
 
M

Michael Mellor

Jonathan said:
How much faster "\n" is than "std::endl" depends critically on what
percentage of character output consists of newlines. Did you compare
the two by writing nothing but newlines, or did you write a sample
text document, such as a web page?
I did say a quick benchmark, so it was just a series of newlines, but
even if you print out lines which are 80 characters long '\n' is
slightly more than 2x faster.

I think I've seen it used in "Hello World!", but I don't recall where.
Stoustrup uses "\n" -- which should come as no surprise.


Why does it annoy you so much? Most of the posts to this newsgroup are
simple demo programs where performance doesn't matter. Maybe posters
think it's more readable.
I realise my annoyance is slightly irrational.

Michael Mellor
 
K

Kevin Goodsell

Michael said:
Most C programs I have come across:
printf("a line\n");
printf("another line\n");
....

and not

printf("a line\n"); fflush(stdout);
printf("another line\n"); fflush(stdout);
....

That would be redundant in most cases - stdout may only be fully
buffered if it can be determined that it is not tied to an interactive
device. The alternatives - line buffering and no buffering - implicitly
flush the stream after the newline.

I don't know how applicable this is to C++. I know that cin and cout are
tied so that things like this are redundant:

std::cout << "Enter a word:" << std::endl;
std::cin >> word;

Of course it makes sense to only flush a stream when there's a
compelling reason to do so. But it doesn't hurt (much) to flush more
frequently. I usually recommend ending all output lines with std::endl
or std::flush until you are sure you know better. Even knowing better, I
only occasionally find a good reason to leave a stream unflushed. I'm
sure I've unnecessarily flushed streams a number of times. Maybe I'll
give it more thought in the future.

-Kevin
 
M

Michael Mellor

Kevin said:
That would be redundant in most cases - stdout may only be fully
buffered if it can be determined that it is not tied to an interactive
device. The alternatives - line buffering and no buffering - implicitly
flush the stream after the newline.
My mistake, I should have wrote:
fprintf(afile, "a line\n");
fprintf(afile, "another line\n");
.....

and not

fprintf(afile, "a line\n"); fflush(afile);
fprintf(afile, "another line\n"); fflush(afile);
.....

Michael Mellor
 
K

Keith H Duggar

Of course it makes sense to only flush a stream when there's a
compelling reason to do so. But it doesn't hurt (much) to flush more
frequently. I usually recommend ending all output lines with std::endl
or std::flush until you are sure you know better. Even knowing better, I
only occasionally find a good reason to leave a stream unflushed. I'm
sure I've unnecessarily flushed streams a number of times. Maybe I'll
give it more thought in the future.

I think this is exactly Michael's point. By virtue of poorly written
books many C++ users don't know there is a difference and they don't
know that they are paying a performance cost. In fact, Michael, do you
know there is an even faster way? Using the inserters for '\n' is
inefficient because they are formatted io and require sentry
construction, format checking, etc. For '\n' all you need to do is :

stream << "some stuff" ; stream.put('\n') ;

Try your benchmarks on that and see how much faster it is.

It is important that C++ users learn these finer points of the
language but when? Is it something that every beginner should learn
early on? As Stroustrup has pointed out many times C++ is a language
that you can learn incrementally always benefiting from improving your
knowledge but you don't have to learn the entire language right away.

However, for this particular case, I agree with Michael. '\n' seems
just as simple and clear to me so why teach beginners the bad habit of
flushing the stream at every turn? I found it more helpful to instead
teach them about std::cerr which is unbuffered. Then they can use
std::cerr for their debugging prints, std::cout for their normal
output and still use '\n' throughout. This gives them the advantage of
learning an efficient habit while still having the advantage of
unbuffered out when need be for "robustness".

Of course, save the stream.put('\n') for extra credit :))
 
L

lilburne

Keith said:
I think this is exactly Michael's point. By virtue of poorly written
books many C++ users don't know there is a difference and they don't
know that they are paying a performance cost. In fact, Michael, do you
know there is an even faster way? Using the inserters for '\n' is
inefficient because they are formatted io and require sentry
construction, format checking, etc. For '\n' all you need to do is :

stream << "some stuff" ; stream.put('\n') ;

Try your benchmarks on that and see how much faster it is.

Or 'stream << "some stuff\n";'

But in most programs using endl instead of '\n' is hardly
likely to be the bottleneck.
 
N

Nick Hounsome

Michael Mellor said:
Alf said:
Most C programs I have come across:
printf("a line\n");
printf("another line\n");
....

If we are getting all performance conscious then have you considered that
this will be more efficient as

printf("%s","another line\n");

or better yet

puts("another line\n");

But I have never ever read a book that does puts("hello world\n") despite it
being a simpler function than
printf whose extra functionality is not used.
 
J

Jonathan Turkanis

Michael Mellor said:
Alf P. Steinbach wrote:
I feel its (endl) readability is somewhat arguable, '\n' means a newline
to me and many other programmers, and if not, you could do something like:

static const char newline = '\n';

stream << "text" << newline;

which could be claimed as being even clearer.

Darlye Walker proposed as an addition to the Boost Libraries a
manipulator "newl" which would output a newline character without
flushing. (He attributes the idea to a post by Dietmar Kuehl at
c.l.c++.m.):

std::cout << "Hello World!" << boost::newl;

There was some interest, but the proposal was rejected. It may be
reconsidered later this year.

Jonathan
 
O

Old Wolf

That's ill-considered.
Darlye Walker proposed as an addition to the Boost Libraries a
manipulator "newl" which would output a newline character without
flushing. (He attributes the idea to a post by Dietmar Kuehl at
c.l.c++.m.):

std::cout << "Hello World!" << boost::newl;

There was some interest, but the proposal was rejected. It may be
reconsidered later this year.

I propose:
std::cout << boost::char_a;

which is equivalent to
std::cout << 'a';

I also propose
std::cout << boost::char_b;
std::cout << boost::char_c;
std::cout << boost::char_d;
etc.
 
J

Jonathan Turkanis

I propose:
std::cout << boost::char_a;

which is equivalent to
std::cout << 'a';

I also propose
std::cout << boost::char_b;
std::cout << boost::char_c;
std::cout << boost::char_d;
etc.

Excellent idea! I encourage you to submit it. In fact, I think you
should propose it to the standards committee.

Newline is treated as a special character for a number of purposes, so
it makes sense to want to make it stand out in the code. People who
use endl for this purpose alone are making a mistake.

Jonathan
 
Joined
Mar 23, 2008
Messages
1
Reaction score
0
Really? You think people should stop using it just because it annoys you? Who are you to make such a statement?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top