C++23 <print>库是否修复了‘Hello, World!’输出失败未检测问题?
什么是「Hello, World!」bug
所谓「Hello, World!」bug,指的是当程序向标准输出写入内容(比如经典的Hello World)时,如果遇到写入失败(例如输出到/dev/full这类无剩余空间的设备),程序默认不会主动报告错误,看似正常退出但实际写入操作已失败。这类问题容易被忽略,导致数据丢失或操作失败却无提示。
{fmt}库(v9.1.0)的现状
作为C++23 fmt::println写入失败时不会自动抛出异常,必须手动借助C I/O函数检测错误,示例代码如下:
#include <exception> #include <cstdio> #include <cstdlib> #include <fmt/core.h> int main() { fmt::println( stdout, "Hello, world!" ); if ( std::fflush( stdout ) != 0 || std::ferror( stdout ) != 0 ) [[unlikely]] { return EXIT_FAILURE; } }
C++23 库的错误处理能力
C++23的
#include <print> #include <exception> #include <cstdio> #include <cstdlib> int main() { try { std::println( stdout, "Hello, world!" ); } catch ( const std::exception& ex ) { return EXIT_FAILURE; } }
根据C++23标准,std::println(包括接受C FILE*指针的重载)会自动处理写入和刷新操作的错误:当输出失败时,会抛出std::system_error异常(派生自std::exception),无需手动调用fflush或ferror检测。
不同语言的处理对比
主动报告错误的语言:Rust、Python3、C#等。例如Rust的
println!宏在写入失败时会直接panic并输出明确错误信息:fn main() { println!( "Hello, world!" ); }执行
./main > /dev/full后输出:thread 'main' panicked at 'failed printing to stdout: No space left on device (os error 28)', library/std/src/io/stdio.rs:1008:9
默认静默失败的语言:C++传统iostreams、C、Ruby、Java等,这类语言默认不会在程序退出前主动报告输出流的写入失败,需要开发者手动检测错误状态。
内容的提问来源于stack exchange,提问作者digito_evo

