std::endl(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

✨ std::endl(3) ✨

okay so bestie, welcome to the std::endl glow-up πŸ’… this is a page from the C++ Standard Library manual, and honestly? it's giving "small function, big drama." let's get into it 🫢


🌸 NAME 🌸

std::endl β€” literally just std::endl, bestie. that's the whole name. iconic behavior tbh. ✨


πŸ¦‹ SYNOPSIS πŸ¦‹

first things first: it's defined in header <ostream> πŸ“Œ no cap, that's where you'll find it.

and here's the signature, copied exactly so you can trust me:

template< class CharT, class Traits >
std::basic_ostream<CharT, Traits>& endl( std::basic_ostream<CharT, Traits>& os );

so what does it actually do? it 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(). periodt. πŸ’–

this is an output-only I/O manipulator, which means you can call it with an expression like out << std::endl for any out of type std::basic_ostream. so easy. so clean. we love a one-liner. πŸŽ€


🧚 NOTES 🧚

okay this is the part where the page gets real with you, so listen up πŸ‘‘

this manipulator may be used to produce a line of output immediately β€” for example when you're:

  • displaying output from a long-running process πŸ•°οΈ
  • logging activity of multiple threads 🧡
  • logging activity of a program that may crash unexpectedly πŸ’€ (yes, really, it can just crash, and you want your logs to survive the carnage)

an explicit flush of std::cout is also necessary before a call to std::system, if the spawned process performs any screen I/O. don't skip that step, bestie. πŸ™ˆ

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(). so like… it's already handled, bestie.

and now the spicy part 🌢️ β€” use of std::endl in place of '\n', encouraged by some sources, may significantly degrade output performance. yikes. not every source on the internet is your friend, fr fr.

in many implementations, standard output is line-buffered, and writing '\n' causes a flush anyway, unless std::ios::sync_with_stdio(false) was executed. so in those situations, unnecessary endl only degrades the performance of file output, not standard output. slay for knowing the difference. ✨

the code samples on this wiki follow Bjarne Stroustrup and The C++ Core Guidelines in flushing the standard output only where necessary. we're matching energy with the legends. πŸ‘‘

when an incomplete line of output needs to be flushed, the std::flush manipulator may be used. 🌊

when every character of output needs to be flushed, the std::unitbuf manipulator may be used. 🧼


🌈 PARAMETERS 🌈

  • os β€” reference to output stream 🫢

⭐ RETURN VALUE ⭐

returns os β€” a reference to the stream after manipulation. it gives you back the same stream you handed it, all fresh and flushed. main character energy, truly. πŸ‘‘


πŸ”₯ EXAMPLE πŸ”₯

and here's the example, verbatim, because I would never mess with your code πŸ’–

with '\n' instead of endl, the output would be the same, but may not appear in real time. ⏱️ (so the vibes would be the same, but the timing wouldn't.)
// Run this code

#include <chrono>
#include <iostream>

template<typename Diff>
void log_progress(Diff d)
{
    std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(d)
              << " passed" << std::endl;
}

int main()
{
    std::cout.sync_with_stdio(false); // on some platforms, stdout flushes on \n

    static volatile int sink{};
    const auto t1 = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < 5; ++i)
    {
        for (int j = 0; j < 10000; ++j)
            for (int k = 0; k < 20000; ++k)
                sink += i * j * k; // do some work
        log_progress(std::chrono::high_resolution_clock::now() - t1);
    }
}

πŸ’œ Possible output πŸ’œ

566ms passed
1133ms passed
1699ms passed
2262ms passed
2829ms passed

look at those numbers just… appearing in real time. obsessed. 😭✨


πŸŽ€ SEE ALSO πŸŽ€

  • unitbuf β€” controls whether output is flushed after each operation (function) 🧼
  • nounitbuf β€” the opposite vibe of the above (function) 🚫
  • flush β€” flushes the output stream (function template) 🌊
  • flush β€” synchronizes with the underlying storage device (public member function of std::basic_ostream<CharT,Traits>) πŸ’Ύ

okay that's the whole page bestie, you ate that πŸ“ this fine piece of documentation came from http://cppreference.com, dated 2024.06.10, and it's the std::endl(3) page. go forth and flush responsibly πŸ’…βœ¨

πŸ“¦ where this page comes from