-
Notifications
You must be signed in to change notification settings - Fork 5.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal to outlaw std::endl #357
Comments
Or better yet, why not introduce a new manipulator instead of cluttering up the string #include <iostream>
namespace std
{
std::ostream&
newl(std::ostream& cout)
{
return cout << "\n";
}
}
int main(void)
{
std::cout << "foo" << std::newl
<< "bar" << std::newl << std::newl
<< "baz" << std::newl;
std::cout << "Some log-statement" << std::endl; //< Since we want to flush in this case
} |
I strictly oppose that: There really is nothing wrong with a normal newline character and there is exactly no reason not to use that. I don't know what you consider cluttering about it, but the one thing that is cluttered (apart from being still slower than just the one write I argue for) is everything where manipulators are used for something perfectly normal like a newline. |
I completely agree with this proposal. std::endl should be deprecated from now on. |
The reasoning behind the manipulators is to separate formatting from content... Joining formatting with content in a string is cluttering... |
And since newlines are part of the content… |
+1 for "premature pessimization". The reasoning is just, the benefits are there. Still, this sounds too radical to me (maybe I'm being resistant to change...) Where that issue is indeed relevant to me (nowhere except competitive programming & small tools) I use a I'd propose a guideline to avoid using |
Interaction doesn't usually require flushing, either, thanks to the cin/cout and cerr/cout ties. |
In my reasoning I think that It says that I am finished with this line of content and I will like to send it off to the output stream It is totally different from saying I want to insert a new line at this point... |
@cubbimew that's true, forgot about it because I usually disable it too. What were the reasons that @RicoAntonioFelix In my reasoning ending a line has nothing to do with my intentions of flushing or not. At least is not intuitive why there would be a relationship. I use |
While I agree that endl isn't clearly named, I don't really want to lose it either because I do use it intentionally. (That is, I use '\n' for newline and endl for newline with flush.) Maybe a guideline that detects endl within a stream instead of at the end, or looks for patterns indicating excessive endl use? Addressing the core issue, I would suggest renaming endl, except that it seems fairly entrenched at this point. Maybe introducing a synonym would be an appropriate first step? |
@villasv I have captured this reasoning by relating it to other concepts... For instance, if you were typing and e-mail or an instant message or a comment as this one, at the From this reasoning it can be related to |
I am positive that the reasoning was like this:
And then everyone started using a flush-operation that also prints a newline whenever a newline was needed. |
One must remember that the concept of a stream is a sequence of characters divided into lines where each line consist of zero or more characters followed by the newline character Hence when we think about |
Huh? Where's that coming from? |
@khatharr What is what coming from? |
I've never heard it expressed that way before. |
That definition was provided in Since |
I'll check it out. ty |
The section you're quoting is discussing the difference between text and binary streams rather than attempting to define a paradigm for streams to observe. The significant point about the newline character in the passage is that text streams employ it to break lines. There's no discussion of flushing buffers along with this.
It's also specifically discussing C, as indicated by discussion about CRT implementation requirements which immediately follows that. C stdio is not the basis of C++ streams, though they overlap conceptually in places. It's worth noting, for example, that cstdio does not have a std::endl analog. In the case of std::ostream (where std::endl is relevant), it's very wasteful to use std::endl at the end of every line, which is exactly why Florianjw raised this issue. You used the example of an email earlier, but what you're suggesting is not analogous to sending the full email. It's analogous to sending one message via several emails, with each mail containing one line of text. Actually, mulling this over a bit more, I'm coming to agree with Florianjw. It's really more consistent to just use "\n" << std::flush rather than omitting the last "\n" and using std::endl, and it prevents the problem of overuse. |
It used to be in C++ that the type of 'x' was int, and so cout<<'\n' would On Sun, Oct 25, 2015 at 12:37 AM, Khatharr notifications@github.com wrote:
|
That may explain the infuriating behavior of streams when dealing with chars, but I don't think it would really explain endl, since the correct thing to do in that case would be to learn the difference between single and double quotes, and also because endl flushes the stream. |
Maybe this link might add some merit to this discussion... Pointing out something that's relevant, it states:
This captures the essence of what I was trying to point out from the quote in the book... If such is the case, then @Florianjw's code example deems irrelevant to the point she is trying to make... |
endl relates to ostream, not to cout. C++ is not responsible for implementation behavior.. |
|
Even if you are trying to base your argument on this principle, everything still has context and the context of dealing with a storage device (files) is different from the context of dealing with a character output device... In my view one should understand the differences in context at any particular point and use the appropriate construct... |
Oh my god, Rico... -.- |
I'm just being deliberately critical and thoroughly analysing this proposal... At the end of all this, whatever the community decides will always override one person's view... |
My fault. I'm frustrated because I'm not communicating clearly. Sorry. |
Still, although it makes sense for You can see it either ways. Stringstream has a "dumbed down" behavior because it's a "fake" output stream... or device output has extra functionality because it normally has expected behavior of flush when feeding newlines. I can agree with both lines of reasoning. What I find important in this proposal is highlight the fact that |
I added SL.50: Avoid |
isocpp/CppCoreGuidelines#357 Change-Id: Iebfb13e4e03859e66811b6a6c9a3fe9d1b8f85a5 Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
One doesn't use iostreams for efficiency. Using
Avoiding |
Why not? In my tests iostreams are slightly faster than |
@galic: It took some googling to find some test results. As far as I remember the committee didn't include numbers about this in their performance report, and anyway that's very old. (https://cristianadam.eu/20160410/c-plus-plus-i-slash-o-benchmark/) is from 2016, scroll to bottom for conclusion. You're right about considerably degrade, but the some situations where that matters are rare. Just say no to premature optimization. It comes at high cost. |
@alf-p-steinbach When I run the test you linked I still get iostreams coming out a shade faster.The linked results seem to be more of a Regarding premature optimization I agree. But I don't think that means we should write gratuitously inefficient code either. After all, buffering is an optimization. Why work to defeat the optimizations that are already in place? It costs nothing to state only what you want to do (which is to issue a new line). I am pretty sure it is rare for code to need to flush at the same time. |
Adding to the previous point regarding flushing: As an embedded developer, I rarely want to flush every line. Usually I just want to rely on my system logic to flush whenever appropriate.
Cheers,
Phillip
… On Aug 3, 2017, at 21:22, Galik ***@***.***> wrote:
@alf-p-steinbach When I run the test you linked I still get iostreams coming out a shade faster.The linked results seem to be more of a Visual C++ problem rather than iostream. I am not able to test Visual C++ here. The strange thing about the test results published there is that the test is for copying binary files, not formatted i/o. I would have thought those operations would be largely governed by the disk performance. How the library writers managed to get such bad results is a mystery to me. It is almost like every buffer is being copied (several times) before being flushed? Maybe by now the MS library is fixed.
Regarding premature optimization I agree. But I don't think that means we should write gratuitously inefficient code either. After all, buffering is an optimization. Why work to defeat the optimizations that are already in place? It costs nothing to state only what you want to do (which is to issue a new line). I am pretty sure it is rare for code to need to flush at the same time.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or mute the thread.
|
But perhaps ye ol' |
I can't understand how this can generate so much discussion. If you want a newline, insert a newline. If you want a newline and a flush, insert |
"Understand what |
I'm coming to this issue after several months of heavily studying and learning C++ and using So there's one data point 😃. As a developer, I totally understand the mentality of "understand what |
I think @BrianSipple puts a very good reason for why |
The guideline already exists for two years now - what is your point? |
Eliminates extra call. isocpp/CppCoreGuidelines#357
Just FTR: if only it had been called |
Did you really just necro a 6-year-old thread to post a hypothetical scenario that is never going to happen with a subpar solution |
@Cleroth Did you really just get triggered by that? :-o This is not a gaming forum. This is not a social media thread for organizing family events. There are no weird rules to forbid that either. FTR, these issue conversations are knowledge repositories, i.e. a timeless public space for exchanging and recording ideas. Too bad you spammed it with your irritated policing comment, and kinda forced me to follow it up, too, resulting in two more notifications. |
Writing a
std::endl
to a stream is exactly equivalent to writing a'\n'
, followed by astd::flush
to a stream. In my experience very few people are aware of the later part and for some reason assume that it is instead a portable way to print a newline (which it technically is, but so is'\n'
). Many of them are surprised, sometimes shocked, when they learn the truth, because they excessively use it in their codebase whenever they need a newline, thereby slowing down everything for no gain at all. (This is premature pessimization!)Even for people who are aware of the truth this can be a disadvantage because they have to find out whether the flush is really necessary in the particular place, or whether they can replace multiple writes with one.
The following is similar to what I've seen in the wild:
This can be replaced with
Which is just one write-call and additionally improves readability by reducing line-noise (this is even more true in editors that highlight escape-sequences).
For the few cases where flushing is really desired,
std::flush
works perfectly well and actually states the intent:std::cout << "Some log-statement\n" << std::flush;
The text was updated successfully, but these errors were encountered: