Created on 2026-02-24.00:00:00 last changed 1 week ago
According to [format.formatter.spec] p2 bullet (2.2), the C++ spec specifies formatter<charT[N], charT> specialization as enabled, but it doesn’t specify how it formats the array.
Currently there is implementation divergence on this:libstdc++ formats all characters of the array,
while libc++ and MSVC format up to the first null character.
This can be observed by the following code example (See also godbolt demo, last one shows the outcome for fmt library):
#include <print>
template<typename T>
struct wrapper {
const T& ref;
};
template<typename T>
struct std::formatter<wrapper<T>, char> {
std::formatter<T, char> underlying;
constexpr auto parse(auto& ctx) { return underlying.parse(ctx); }
auto format(wrapper<T> w, auto& ctx) const { return underlying.format(w.ref, ctx); }
};
int main() {
std::print("{:?}\n", "hello\nworld");
std::print("{:?}\n", wrapper("hello\nworld"));
}
Clarifying libstdc++ behaviour:
First print statement decays the array into a pointer in basic_format_arg construction: gcc/libstdc-v3/include/std/format#L4535-L4545 gcc/libstdc-v3/include/std/format#L4440-L4443 So it gets formatted through formatter<const char*, char>. The second print statement goes through formatter<char[12], char>, which emits the null character at the end as well. In essence, libstdc++ formatter<char[N], char> formats it as `string_view(arr, N)`, while others format as `string_view(arr)`.| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2026-02-24 00:00:00 | admin | create | |