Should std :: endl be used?

I jump from C to C ++ using the C ++ Primer book (5th edition), where the author claims the following:

Programmers often add print instructions during debugging. such statements should always clear the stream. Otherwise, if the program crashes, the output may be left in the buffer, which will lead to incorrect conclusions about where the program crashed.

But Internet posts offer otherwise; some say that constantly flushing the buffer is bad for the program and causes performance problems.

My questions:

  • When should you use std::endl ?
  • Is the author wrong or didn’t I understand any part of what he stated?
  • Can you give real-world scenarios where flushing the output stream is necessary?

PS

  1. What does buffer flush mean?
+5
source share
6 answers

Point 4 and Point 3

Starting from point 4, because everything else depends on it and point 3, because it is closely related.

When you clear a stream, you take all the data stored in the stream and write it to the underlying media represented by the stream.

When he blushed, he is done, perfect and ready for observation by the outside world (more or less). The operating system and hardware flow support may also delay recording, but you cannot do this). You cannot read it until it turns red. If he never blushed, you cannot read it.

The fact is that you do not want to write to IO very often, because everything that leaves the CPU takes an inhuman amount of time compared to what remains inside the CPU. Tens of thousands of times slower. Inside the processor, there are gigahertz and parallel buses that move data 32 or more bits at a time. Outside, you have megahertz often moving one bit at a time.

Take the file as a classic example. Not only does disk access work at processor speed, but if every byte goes directly to disk, then for each byte you may need

  • find this byte counterpart on disk.
  • loads a sector around this byte into memory. Therefore, instead of moving one byte, you can move several hundred or thousands. Typically 512 bytes or 4096 bytes.
  • write a byte to a sector in memory
  • write sector to memory back to disk

Brutal. Imagine doing this several hundred or several thousand times to write a single line. But what if you only wrote a line when it got too big to hold, or did you finish? What if you write in sectors, not in bytes? Then you could

  • find this byte in the analog sector on disk.
  • write saved sector to disk

One operation for potentially thousands of bytes per shot.

Point 2

Point 2 goes back to point four / three, you cannot read what you are not doing. If you want to see a specific output on the screen, and you want to see it now, you will flash. If you want to receive a debugging message before the program crashes, and most likely will end without receiving the last last absolutely necessary messages on the screen, you will flash. The story is full of programmers who are looking for the wrong place to make a mistake because they have not received those last few messages about common errors.

You trade program speed for relative confidence that you will see an important message when you need to see it.

Point 1

Point 1 refers to point 2. std::endl is both the end of the line and the instruction to reset the stream. You use it sparingly and only when you need both the end of the line and the flash. If you don't need a flash, just send and end the line: '\n' .

Take Pete Becker's advice and use std::cerr for errors and debugging where possible. This is what it was built for. He acts on brute force and ignorance. This is painful. It is slow. And it almost always works.

+2
source

Debug output should be written to std::cerr ; the block is buffered, so each character gets red. std::endl rarely required, and the habit of using it will lead to a mysteriously slow code. Just use '\n' if you do not know what you need to flush the buffer.

+7
source

Both the author and the posts are correct.

stream << std::endl is actually stream << '\n' << std::flush . Explicit flushing has performance flaws and therefore you should not use it in critical situations. You rarely think of such minor performance issues during debugging, so it's actually good practice to explicitly reset the debug output.

+1
source

By default, std::cout is associated with stdout , which ...

fully buffered if and only if the stream can be determined so as not to refer to the interactive device.

(C99, 7.19.3 Files, clause 7.)

This means that if your output is sent to the terminal, std::endl vs. "\n" does not matter in the first place .; -)


Regarding your actual question:

Total:

  • Disabled output buffers may lead to incorrect conclusions about where the program crashed
  • flushing output buffers affects performance

This becomes a problem only after adding “always”.

When should you use std::endl ?

If you want to flush the buffer.

Is the author wrong or did I miss an understanding of any part of what he stated?

I think that absolute quantifiers, such as "always", "all", "never", etc., should be taken with a grain of salt in relation to style / design, etc.

(Exception: never cause undefined behavior. ;-))

Can you give real-time real-time scenarios for the actual need to flush the output stream?

Whenever the last exit is not actually displayed, this is not acceptable. Regardless of whether it matters in any given scenario, it is a court challenge.

Personally, I find production / transaction logs more critical than debug logs ...

0
source

1) When should you use std :: endl?

If you want to be sure that the buffer is flushed immediately.

2) Is the author wrong or did I miss an understanding of any part of what he said?

No, the author is right, and so are you.

3) can you give real world scenarios for the actual need for flushing the output stream?

When a random string is written to the stream many times over a short period of time, std::endl can actually result in performance loss due to unnecessary buffer std::endl every time. However, when it comes to print lines that are added for the sole purpose of debugging, you should always clear the buffer. Again, if you are debugging an application with only print lines, without using a debugger, you are doing something wrong in the first place.

0
source

You should not use std::endl . This is a cargo cult that should disappear. It gives you nothing but a lack of performance. Just make it muscle memory: always "\n" , never std::endl .

-7
source

Source: https://habr.com/ru/post/1243682/


All Articles