-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Why is println
missing?
#428
Comments
What's wrong with |
I think that template <typename... Args>
void println(fmt::CStringRef format, const Args&... args) {
fmt::print(format, args...);
std::putc('\n', stdout);
} |
Sure, and you could always use Having to include an explicit newline everywhere is noisy and prone to forgetting them. There's a reason why many languages include Cheers. |
The difference from fmt::print("foo");
fmt::print(stdout, "foo"); and directly corresponds to |
It's true that void foo(std::string s) {
fmt::print(s);
} considered bad form or bad api usage? |
Yes. As with void foo(std::string s) {
fmt::print("{}", s);
} Otherwise |
For Windows it's: |
You can use |
The underlying streams will translate newlines, as long as they are not binary streams. stdout by default is not, so it will properly translate newlines. |
Ummmm... I like UPDATE: |
It does not flush stream like it do std::endl |
Although not mandated by the C standard, The same applies for |
|
That's a feature. Even with hypothetical |
Still why don't have flushing println()? |
|
I agree that #include <stdio.h>
int main() {
puts("abcde");
} C#: using System;
class Program {
static void Main() {
Console.WriteLine("abcde");
}
} Go: package main
import "fmt"
func main() {
fmt.Println("abcde")
} Rust: fn main() {
println!("abcde");
} Nim: echo "abcde" Python: print('abcde') |
I honestly was shocked this isn't the default behaviour of fmt::print() Usually if you don't want a newline, you can be explicit about this. |
Also verified on Linux Mint. When I do this for example in a Qt application using iostream, i have to put std::endl to be sure that it outputs immediately, otherwise it will arbitrarily show up. |
Yeah it's annoying to explicitly flush the buffer... |
I'd also like to point out that absence of such a basic ergonomic feature in the presence of features like the literal based API is kinda funny 😄 |
The more common use case is println and it is so trivial it should be baked in. typing \n everywhere adds too much noise. |
I would speak against an implicit newline within |
What's the proper way to flush the buffer in current {fmt}? |
@jm4R why do you hijack this thread instead of opening a new issue/question? |
I've just been banging my head off this, I have a legacy logging system that I'm converting to use fmt, and I can't find any way to insert a newline at the end of log statements automatically. The problem is that @vitaut 's five-line println above (which is what I'd tried before finding this) doesn't work where it's being compiled into a library for use by other code. The compiler creates all the function signatures used by my logging code itself, and then as soon as some other piece of code imports the library and tries to pass something to the logger with a combination of types it didn't see during compilation of the logging library, the linker barfs saying it's got an undefined symbol. So yeah. Absent a println it seems I have a choice between requiring all users of the library to start putting their newlines in themselves, or not porting it to fmt. |
Just write your logging functions using perfect forwarding like this: template <typename... Args>
void logWarn(fmt::format_string<Args...>&& fmt_str, Args&&... args)
{
fmt::print(stderr, "warning: {}\n", fmt::format(
std::forward<fmt::format_string<Args...>>(fmt_str), std::forward<Args>(args)...));
}
template <typename... Args>
void logInfo(fmt::format_string<Args...>&& fmt_str, Args&&... args)
{
fmt::print("info: {}\n", fmt::format(
std::forward<fmt::format_string<Args...>>(fmt_str), std::forward<Args>(args)...));
} C++20 automatic compile-time argument checking still works fine with these, and so does manual compile-time checking with |
I think println should be added. In any case many code-bases using this fmt library would write their own println one-liner. So why not to add it here? I've read this thread and didn't find any reasonable argument against it. |
Given that this discussion has been ongoing for 6 years now and that the developers behind fmtlib have shown zero interest in listening, I'd suggest any future commenters to either use the provided workaround, or just move onto other libraries with more active development. I suggest @vitaut locks this issue, as any attempt to further convince you on this issue just adds noise in the repository activity at this point. |
To add a feature there should be strong arguments for it not against not adding it. And so far the arguments have been somewhat lacking and some even became invalid with compile-time checks. @jiri, no plans to lock this issue but at least please stop adding noise yourself. |
@vitaut Please refrain from mentioning me again, I don't wish to continue this discussion with you. Thank you! |
I completely disagree to this approach of feature management. |
|
Would it be reconsidered if implementers add |
Yeah, if P2093 gets adopted it would make sense to be consistent. |
Summary: I noticed that `watchman debug-status` seems to be missing from a lot of `watchman-diags` on macOS. turns out its missing from `watchmanctl rage` too. I discovered that when stdout is piped watchman --pretty debug-status prints nothing. Some more digging and it looks like when stdout is a terminal, its line buffered. So every \n effectively flushes the output. But when stdout is piped or captured by a calling process, its "block buffered". So stdout needs to be manually flushed. I would have thought it would be flushed at the end of the process, but evidently not on macOS? fmt also does not manually flush stdout when you use fmt::print. see: vgc/vgc#519 and fmtlib/fmt#428 (didn't know println was so controversial 😛). We need to manually flush stdout for now to ensure that fmt::print works. Eventually, we can use fmt::flush (because vgc/vgc#519). but that does not seem available in the version of fmt we use today. Reviewed By: genevievehelsel Differential Revision: D40881110 fbshipit-source-id: d417b9c4f932ea08905fd125847c8dd30751eeec
Summary: I noticed that `watchman debug-status` seems to be missing from a lot of `watchman-diags` on macOS. turns out its missing from `watchmanctl rage` too. I discovered that when stdout is piped watchman --pretty debug-status prints nothing. Some more digging and it looks like when stdout is a terminal, its line buffered. So every \n effectively flushes the output. But when stdout is piped or captured by a calling process, its "block buffered". So stdout needs to be manually flushed. I would have thought it would be flushed at the end of the process, but evidently not on macOS? fmt also does not manually flush stdout when you use fmt::print. see: vgc/vgc#519 and fmtlib/fmt#428 (didn't know println was so controversial 😛). We need to manually flush stdout for now to ensure that fmt::print works. Eventually, we can use fmt::flush (because vgc/vgc#519). but that does not seem available in the version of fmt we use today. Reviewed By: genevievehelsel Differential Revision: D40881110 fbshipit-source-id: d417b9c4f932ea08905fd125847c8dd30751eeec
fmtlib/fmt#428 (comment) > You can use fmt::print("...\n") on Windows as well. Use this mechanism instead of tr_sys_file_write_line()
fmtlib/fmt#428 (comment) > You can use fmt::print("...\n") on Windows as well. Use this mechanism instead of tr_sys_file_write_line()
…6619) * refactor: use fmt::print in log.cc fmtlib/fmt#428 (comment) > You can use fmt::print("...\n") on Windows as well. Use this mechanism instead of tr_sys_file_write_line() * refactor: use FILE* in daemon * refactor: remove unused tr_sys_file_flush_possible() * refactor: remove unused tr_sys_file_write_line() * refactor: remove unused tr_sys_file_get_std() * refactor: remove unused tr_std_sys_file_t
Seems C++23 has included the |
@emailstorbala fmt also now has |
oh thank you @hellow554 ! I am using |
As far as I can see on |
…ransmission#6619) * refactor: use fmt::print in log.cc fmtlib/fmt#428 (comment) > You can use fmt::print("...\n") on Windows as well. Use this mechanism instead of tr_sys_file_write_line() * refactor: use FILE* in daemon * refactor: remove unused tr_sys_file_flush_possible() * refactor: remove unused tr_sys_file_write_line() * refactor: remove unused tr_sys_file_get_std() * refactor: remove unused tr_std_sys_file_t
fmt::println
seems like a natural addition to the API. Is there a reason why it's missing?The text was updated successfully, but these errors were encountered: