I massively rewrote ostream based logging in my codebase using _format literal. And suddenly I found out that this is not checked at all. I really like the idea of compile-time checked format because it allows seeing all the problems immediately at the compilation stage, instead of waiting for a crash somewhen in future when the code with {fmt} call will be executed. And it's sad that currently it's almost doesn't working.
Here is a list of compile-time checks that works:
https://godbolt.org/z/cc8MPrGc9
#include <fmt/format.h>
using namespace fmt::literals;
void func() {
fmt::format( "{}", 1, 2 ); // (1) UNCHECKED
fmt::format( "{} {} {}", 1, 2 ); // (2) checked
fmt::format( "{:d} {}", "", 2 ); // (3) checked
fmt::format( "{addr2}", fmt::arg("addr", 1) ); // (4) UNCHECKED
fmt::format( "{addr2}", "addr"_a = 1 ); // (5) UNCHECKED
"{}"_format( 1, 2 ); // (6) UNCHECKED
"{} {} {}"_format( 1, 2 ); // (7) UNCHECKED
"{:d} {}"_format( "", 2 ); // (8) UNCHECKED
"{addr2}"_format( fmt::arg("addr", 1) ); // (9) UNCHECKED
"{addr2}"_format( "addr"_a = 1 ); // (10) UNCHECKED
}
- 1,6 - too many arguments. Unchecked at all
- 2,7 - too few arguments. Checked only in fmt::format
- 3,8 - incorrect format flags. Checked only in fmt::format
- 4,9 - incorrectly named arguments using fmt::arg. Unchecked at all
- 5,10 - incorrectly named arguments using _a literal. Unchecked at all
Is there a chance that some unchecked scenarios, especially with _format literals would become checked? Now it seems quite inconsistent and confusing.
P.S. I checked only gcc10 and gcc11 with trunk {fmt}. So maybe they don't work only under some list of compilers.
I massively rewrote ostream based logging in my codebase using _format literal. And suddenly I found out that this is not checked at all. I really like the idea of compile-time checked format because it allows seeing all the problems immediately at the compilation stage, instead of waiting for a crash somewhen in future when the code with {fmt} call will be executed. And it's sad that currently it's almost doesn't working.
Here is a list of compile-time checks that works:
https://godbolt.org/z/cc8MPrGc9
Is there a chance that some unchecked scenarios, especially with _format literals would become checked? Now it seems quite inconsistent and confusing.
P.S. I checked only gcc10 and gcc11 with trunk {fmt}. So maybe they don't work only under some list of compilers.