Title
Unclear specification for formatter<charT[N], charT>
Status
new
Section
[format.formatter.spec]
Submitter
Ivan Lazaric

Created on 2026-02-24.00:00:00 last changed 1 week ago

Messages

Date: 2026-02-24.00:00:00

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:00admincreate