Has anyone ever seen this std::endl quirk?

  • Thread starter Dr Transport
  • Start date
In summary, when printing to a scrolling window, a std::end takes about 0.5 ms on my system. (unless there was no output between endl's) and printing the numbers from 1 to 10000 takes 13 seconds with std::endl between the numbers, and only 8 seconds with "\n" .
  • #1
Dr Transport
Science Advisor
Insights Author
Gold Member
2,607
802
Yesterday afternoon, instead of doing real meaningful work I was screwing around with <threads> on my Debian box at work. I've been spending some time looking at converting some of our codes and working on getting them parallelized better. Like most legacy codes, the parallel part was really an afterthought. So on to my question. The basic hello world via threads works pretty well but I noticed a quirk in the output. When I tried to use
Code:
 std::cout << ...  << std::endl;

to end the line and add a newline, it didn't work, but if I typed in

Code:
 std::cout << "...\n";

the next output line was on the next line. Anyone ever seen this before? The code compiles correctly without any errors, just doesn't behave as I would expect. Now I didn't try it with another program, although I did write a hello world to play with the g++ compiler previously and didn't see this issue.
 
Technology news on Phys.org
  • #2
I've seen something similar to this when I was recently doing a simple program with threads, so maybe my explanation will be pertinent, or maybe not.

It's possible that the std::endl character gets written, but only to the output buffer, not to the output stream itself (the monitor). I don't know why the behavior would be different with a newline character appended directly to the string your printing, but perhaps in this case, it's one operation as opposed to a separate call to cout << std::endl; .

Just a guess...
 
  • Like
Likes jedishrfu
  • #3
You could try repeating the line to see if all but the last endl; makes it through.

This could be a buffer flushing issue that the thread gave up control before it flushed the endl out.
 
  • #4
The moral of the story is don’t be doing simple programs. :-)
 
  • #5
Dr Transport said:
to end the line and add a newline, it didn't work, but if I typed in
You can do that? - output a bunch of "..." without the quotes??
 
  • #6
256bits said:
You can do that? - output a bunch of "..." without the quotes??
I think he was just making a shortcut, with ... representing some delimited string.
 
  • Like
Likes jedishrfu
  • #7
jedishrfu said:
This could be a buffer flushing issue that the thread gave up control before it flushed the endl out.
I was thinking this when I wrote my reply, but didn't mention it, about the thread giving up control prematurely.
 
  • Like
Likes jedishrfu
  • #8
cout << "\n" is likely significantly faster than cout << std::endl; because the latter does cause a flush every time.
When printing to a scrolling window, a std::end takes about 0.5 ms on my system. (unless there was no output between endl's)
printing the numbers from 1 to 10000 takes 13 seconds with std::endl between the numbers, and only 8 seconds with "\n"
So don't use endl unless you want to flush (there are youtube movies about this).
 
  • #9
At this point in time I am not worried about speed but wondering why endl; isn't working and flushing the buffer on some of these systems is a good thing.

As for giving the thread giving up the control, this was a cout statement in the main function, not in the spawned thread, which hadn't been called yet.
 
  • #10
Buffers are usually flushed when full or when a file is closed or forced to explicitly. I don’t think endl will force it explicitly.
 
  • #11
From what find yesterday, endl; is defined as a \n followed by std::flush, so the flush is inherent in the function call...

I even tried to add a flush; for grins and the carriage return still didn't happen.
 
  • #12
So you're saying if you do a \n and flush explicitly, it works, but if you use an endl, which is defined as \n and flush it doesn't?
 
  • #13
To be clear a line feed aka \n and cr aka \r are not the same. On windows lines end in crlf whereas on unix variants it’s just \n

You implementation may in fact not flush on endl but it’s not a problem usually because eventually the buffer does get flushed.
 
  • #14
Vanadium 50 said:
So you're saying if you do a \n and flush explicitly, it works, but if you use an endl, which is defined as \n and flush it doesn't?
I didn't do a \n then a flush. I did do an endl; then tried a flush and there was no carriage return. The \n alone did result in a carriage return. Monday I'll try a few more things.
 
  • #15
@Dr Transport , I don't see that you have answered @256bits question:
256bits said:
You can do that? - output a bunch of "..." without the quotes??
Should we take your post literally with the ... and no quotes? If so, then I think the print statement is not valid.
 
  • #16
256bits said:
You can do that? - output a bunch of "..." without the quotes??

FactChecker said:
@Dr Transport , I don't see that you have answered @256bits question:

Should we take your post literally with the ... and no quotes? If so, then I think the print statement is not valid.

I think that these prior threads answers the question... no quotes necessary...
 
  • #17
FactChecker said:
@Dr Transport , I don't see that you have answered @256bits question:

Should we take your post literally with the ... and no quotes? If so, then I think the print statement is not valid.
It didn't need answering, @Mark44 seemed to be the only one who interpreted my post without reading too much into it. And no one has responded with a viable reason to the OP... Frankly I didn't think I needed to be so explicit and I figured the readers of this forum would be able to interpret a shorthand notation.
 
  • #18
Dr Transport said:
And no one has responded with a viable reason to the OP
I think our responses about buffers not getting flushed prior to a thread context switch is a likely reason.
Dr Transport said:
Frankly I didn't think I needed to be so explicit and I figured the readers of this forum would be able to interpret a shorthand notation.
I agree.
 
  • #19
Mark44 said:
I think our responses about buffers not getting flushed prior to a thread context switch is a likely reason.

Dr Transport said:
Frankly I didn't think I needed to be so explicit and I figured the readers of this forum would be able to interpret a shorthand notation.

I agree.

I agree with that, but it still does not explain why no carriage return isn't occurring, I wasn't able to recreate the same issue on another machine I have access to, the endl; resulted in a carriage return/newline whereas on the original machine I was working on it did not.

when I looked for further documentation online about the standard, endl; was explained as a carriage return followed by a flush().

As for the interpretation of what someone writes, I am at a loss, pretty much every thread on this forum takes a fair amount of interpretation to interpret someones thoughts and I have seen many threads which haven't been able to be deciphered.
 
  • #20
Dr Transport said:
It didn't need answering, @Mark44 seemed to be the only one who interpreted my post without reading too much into it. And no one has responded with a viable reason to the OP... Frankly I didn't think I needed to be so explicit and I figured the readers of this forum would be able to interpret a shorthand notation.
When faced with a computer code, computers take things very literally, and so should computer programmers. Pleas don't make us guess about your bugs. It's much less effort on your part to answer the question than it is on our part to guess what you really meant.

In any case, you should really consider that the ... might be hiding a bug.
 
  • #21
Do you print anything after the std::endl that you do see? If so, then the output buffer has been flushed. If you do print more and do not see it, then it may not have flushed the buffer.
 
  • #22
FactChecker said:
In any case, you should really consider that the ... might be hiding a bug.
The line with the ellipsis, ..., wasn't meant to be taken literally. I surmised that in post #6, and Dr Transport confirmed it in post #17.
 
  • #23
Mark44 said:
The line with the ellipsis, ..., wasn't meant to be taken literally. I surmised that in post #6, and Dr Transport confirmed it in post #17.
I think that @FactChecker understands this. When he says
FactChecker said:
In any case, you should really consider that the ... might be hiding a bug.
he means that the omitted code might contain something that is related to the problem observed. I think we've all seen it often at PF: the bug is not always where people think it is.
 
  • Like
Likes FactChecker
  • #24
DrClaude said:
I think that @FactChecker understands this. When he says

he means that the omitted code might contain something that is related to the problem observed. I think we've all seen it often at PF: the bug is not always where people think it is.
I understand, but in this case, what was omitted was not germain to the issue brought up "..." was meant to replace any random textual output that contained no other control characters... and anything printed out to the screen after is on the same line and no new line feed is seen until I manually insert a "\n".
 
  • #25
Dr Transport said:
I understand, but in this case, what was omitted was not germain to the issue brought up "..." was meant to replace any random textual output that contained no other control characters... and anything printed out to the screen after is on the same line and no new line feed is seen until I manually insert a "\n".
You may think that the surrounding code is not germane, but that assumption is often wrong. A better approach for debugging is to test a simple, minimal example. If the unexpected behavior is still there then you can show us more precisely what your code is. If the problem disappears, that is a definite clue. When issues with a flushed buffer are a factor, you need to know how much was or was not printed before and after the newline. Your test case should include prints before and after the missing part.

PS. One thing about your first post that confused me was that one case did not have ... in quotes but the second case did, as though it should be taken literally.
 
Last edited:
  • #26
I have provided all the information I will provide. My quote unquote in the second case quoted the first and was not meant to be confusing.

I provided all that was germane to the problem, I'm sorry you were unable to read what I wrote and help in any way..., again, the ... was meant as a place holder, nothing more, nothing less and in my last post it meant to replace un-formatted text without any control characters, case closed.
 
  • #27
Dr Transport said:
It didn't need answering, @Mark44 seemed to be the only one who interpreted my post without reading too much into it. And no one has responded with a viable reason to the OP... Frankly I didn't think I needed to be so explicit and I figured the readers of this forum would be able to interpret a shorthand notation.
Yes . I was kind of loose with my fingers, ( and of course brain but I can't admit that :oops: ).
 
  • #28
Since you tried it on another machine and the problem didn't show up, it could be
  • a compiler bug
  • some other part of the program rewriting memory it is not supposed to
Try changing the compiler options to see what happens (in particular optimization level). Also, check if the compiler versions are the same on the computers with and without the bug.
 
  • #29
DrClaude said:
Since you tried it on another machine and the problem didn't show up, it could be
  • a compiler bug
  • some other part of the program rewriting memory it is not supposed to
Try changing the compiler options to see what happens (in particular optimization level). Also, check if the compiler versions are the same on the computers with and without the bug.

I suspect it is a compiler bug, the work computer I was on is running an older version of Debian (my group doesn't update OS's or computers until they absolutely have to and frankly the guy who took it upon himself to keep things running is so OCD that any little change to his routine causes him to start at step one, so when it is running he won't change anything). The version of Debian I didn't see it was the latest version, so I think they fixed it.

Thanks
 

Related to Has anyone ever seen this std::endl quirk?

1. What is the purpose of "std::endl" in code?

"std::endl" is a C++ standard library function that is used to insert a new line character and flush the output stream. It is commonly used in code to end a line of output and move the cursor to the next line.

2. Why is "std::endl" sometimes called a "quirk"?

"std::endl" is often referred to as a "quirk" because it can cause unexpected behavior in code if used incorrectly. For example, using it unnecessarily can result in slower performance and it may not be necessary for simple output operations.

3. How does "std::endl" differ from "\n" in code?

While both "std::endl" and "\n" are used to insert a new line character, they differ in functionality. "std::endl" also flushes the output stream, meaning it forces any buffered characters to be written to the output immediately. "\n" does not have this additional functionality and is simply used to create a new line.

4. Can using "std::endl" cause any errors in code?

While using "std::endl" is generally considered safe, it can cause errors if used incorrectly or excessively. For example, using it in a loop can result in slower performance and may not be necessary. Additionally, using it on a stream that is not open may result in an error.

5. Is it necessary to use "std::endl" in every line of output?

No, it is not necessary to use "std::endl" in every line of output. In fact, it is often recommended to use "\n" instead for simple output operations. "std::endl" should only be used when the output stream needs to be explicitly flushed, such as in cases where you need to ensure the output is immediately written to the screen or file.

Similar threads

  • Programming and Computer Science
Replies
5
Views
1K
Replies
10
Views
1K
  • Programming and Computer Science
3
Replies
89
Views
4K
  • Programming and Computer Science
Replies
1
Views
1K
  • Programming and Computer Science
Replies
6
Views
1K
  • Programming and Computer Science
3
Replies
75
Views
5K
  • Programming and Computer Science
Replies
2
Views
1K
  • Programming and Computer Science
Replies
23
Views
2K
  • Programming and Computer Science
Replies
1
Views
2K
  • Programming and Computer Science
Replies
5
Views
2K
Back
Top