cout << "Hello, World!" << '\n';
But the most "modern" way to write to the console is: std::println("Hello World!"); cout << "Hello, World!" << '\n';
But the most "modern" way to write to the console is: std::println("Hello World!");I was reading a lot of c++ core guidelines and modern c++ blogs and books while writing a little game a couple of years ago and std::println was definitely not the common suggestion for modern c++. I see it's probably because it wasn't even available at the time. Now I feel like I'd have to review everything that I thought was modern two years ago to confirm that it is still the modern way.
In C you control this with setvbuf, and of course, in C++ with iostreams it's a huge mess of rdbuf spaghetti and probably involving std::ios_base::sync_with_stdio as well.
You can observe this by printing out tens of thousands of lines with vs without explicit flushing, there will be a big performance difference.
I've tested that I'm correct on glibc, where the behavior is documented here: https://www.gnu.org/software/libc/manual/html_node/Buffering...
I can't remember using an alternative platform that behaves differently.
A better test than the one you ran is to look at the resulting syscalls from a loop of `fputs("a line of output.\n", stdout);`, vs. `fputs("a bit of output. ", stdout);`. Buffering accumulates strings in memory before an eventual write syscall, so looking at syscalls is an easy way to see the difference: a write per-'\n' means line buffering.
Compare the syscalls of both using strace. I did so, and when stdout is to the terminal, I see lots of calls to `write(1, "a line of output\n", 17)` compared to `write(1, "a bit of output. a bit of output"..., 1024)`. (To confirm, manually insert an `fflush(stdout);` in the "a bit of output. " version, and you'll see lots of `write(1, "a bit of output. ", 17)`)
Then compare both when redirecting stdout to a file, and you'll see both cases make large write-s of 4KB. Only adding explicit fflush-es will make either version go back to small write-s of 17B.
Compiled the trivial test programs with `cc -O2 ./main.c -o ./main`
So I'm correct on those targets as well.
Looking for write syscalls is not a valid way to figure out where buffering is happening.
Write by default is famously buffered in Linux, and stdio/iostresm functions map closely to it. So, if you call these C functions N times, you'll see write being called N times.
Flushing calls fsync or some ioctl depending on the file descriptor is, iirc.
I meant to reply much sooner, with more info from empirical tests. But now I'm happy to leave it at just the write stuff and the note about the meaning of stdio/iostream "flushing".
I think you have an incorrect or esoteric understanding of what the "buffering" in question is, but it doesn't matter to me. My argument is about what syscalls happen, and I don't care if you disagree with the (I think, standard) descriptor/terminology I'm using.
Probably because it has only been available since C++23: https://en.cppreference.com/w/cpp/io/println.
The only significant difference I see is that std::println automatically includes the newline which may or may not be desired behavior.
Accepted paper here: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p20...
> The proposed std::print function improves usability, avoids allocating a temporary std::string object and calling operator<< which performs formatted I/O on text that is already formatted. The number of function calls is reduced to one which, together with std::vformat-like type erasure, results in much smaller binary code (see § 13 Binary code).
Additionally,
> Another problem is formatting of Unicode text:
> std::cout << "Привет, κόσμος!";
> If the source and execution encoding is UTF-8 this will produce the expected output on most GNU/Linux and macOS systems. Unfortunately on Windows it is almost guaranteed to produce mojibake despite the fact that the system is fully capable of printing Unicode
https://stackoverflow.com/a/4854358/24817 is the canonical explanation for why >> and <<, apparently. Nearby, this is also mentioned:
> C’s printf family of functions is an effective and often convenient I/O mechanism. It is not, however, type safe or extensible to user− defined types (classes). Consequently, I started looking for a type safe, terse, extensible, and efficient alternative to the printf family. Part of the inspiration came from the last page and a half of the Ada Rationale [Ichbiah,1979], which is an argument that you cannot have a terse and type− safe I/O library without special language features to support it. I took that as a challenge. The result was the stream I/O library that was first implemented in 1984 and presented in [Stroustrup,1985].
and
> The stream I/O facility is implemented exclusively using language features available to every C++ programmer. Like C, C++ does not have any I/O facilities built into the language.
The language simply didn't have the advanced tools that ended up being used in more modern solutions yet. It was too early.
As usual, C++'s priorities are wrong for anyone who's not writing an OS, web browser, game engine, or otherwise rare type of project.
I think calling formatted printing “cognitive load” is a bit much though. If anything this is easier to understand and use than stdio and iostreams. It’s closer to other languages in this area. I probably would have voted yes on this if I were on the relevant committee.
1. Incompatible with dynamically-generated format strings, in which the order of arguments is different. Example:
std::cout << month << '/' << day << '/' << year
... but you now want to adapt that for a non-US locale, e.g. a European one where it's std::cout << day << '/' << month << '/' << year
with iostreams, you have to change the code. With C-style printf, you don't (but it's not typeafe and not flexible. But with std::print it could be: std::printf(my_format_str, day, month, year);
and `my_format_str` could be either "{0}/{1}/{2}" or "{1}/{0}/{2}".2. The string allocations which other have mentioned.
3. A lot more typing that is easy to confuse: " << ".
4. The iostreams implementation is super-baroque, with buffer classes nobody uses.
and maybe I'm forgetting things.
Std:seems std:confusing
You can answer your own question if you google "println cppreference".
More seriously, though - the language is changing gradually: Features are introduced (and rarely, deprecated); and the missing bits of the standard library are added. C++11 was a _very_ significant change - but not to how you print output. C++20 and C++23 introduced `std::format` and `std::print`.
Many people can already write "import <std>;" instead of many lines of "#include <...>".
I imagine targeting C++17 or 20 for 'modern' would be practical enough considering thats what you are most likely to run into in a professional setting.
std::println is, yes.
> I wonder how available this is within compilers
https://en.cppreference.com/w/cpp/compiler_support says clang, gcc, and msvc all support it, though I don't know how recent those versions are off the top of my head.
In my understanding, with this specific feature, if you want a polyfill for older compilers, or to use some more cutting-edge features that haven't been standardized yet, https://github.com/fmtlib/fmt is available to you.
Where did you find it? Search by println yields no results.
Formatted output library <print>gcc 14 has not yet been released; going by past years, 14.1 should come out around the start of May (2024). clang 17 was released September (2023); note that you need to use libc++ (stlib=libc++), not libstdc++. VS 2022 17.7 has been out since August.
So iostreams were a mistake, they shouldn’t have happened in the first place. And given that they happened, std::format should have been added 20 years ago, or at least in C++11.
The problem is that many professional shops never used iostreams, and instead hand rolled their own format library. Now, they don’t really care about std::format, and probably will never use it, because it would involve migrating off of their hand rolled solution which is working great.
On the other hand, for small shops and hobbyists that don’t have the resources to reimplement std, this is a huge quality of life improvement. Meanwhile, more modern languages like Rust are encroaching.
And this is all just about how to print “Hello World!”. This situation is really emblematic of the challenges faced by the C++ committee. It is really impossible to please everyone, or even a majority, since the community is so fractured.
Type detection, formatting options, positional-arguments, custom formatters for custom types and probably more are all supported.
Most existing code probably uses output streams with << operators, it’s good to know what that does.
Indeed, as mentioned [0] at cppcon 2022 :)
[0]: https://youtu.be/eD-ceG-oByA?list=PLHTh1InhhwT6c2JNtUiJkaH8Y...