This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of Resolved status.

### 3336. How does `std::vformat` handle exception thrown by formatters?

Section: 20.20.5 [format.functions] Status: Resolved Submitter: Tam S. B. Opened: 2019-11-11 Last modified: 2020-09-06

Priority: 2

View all other issues in [format.functions].

View all issues with Resolved status.

Discussion:

The specification for `std::vformat` in 20.20.5 [format.functions]/7 says

> Throws: `format_error` if `fmt` is not a format string.

It seems unclear whether `vformat` throws when an exception is thrown by the `formatter`, e.g. when the format string is valid, but the corresponding argument cannot be formatted with the given format string.

For example, the `"c"` format specifier is specified to throw `format_error` if the corresponding argument is not in the range of representable values for `charT` (Table 60 [tab:format.type.int]). It seems unclear whether `vformat` propagates this exception.

It also appears unclear whether `vformat` may throw other types of exception (e.g. `bad_alloc`) when the formatter or the constructor of `std::string` result throws.

[2019-11-20 Issue Prioritization]

Priority to 2 after reflector discussion.

[2019-11-20; Victor Zverovich provides initial wording]

Previous resolution [SUPERSEDED]:

> This wording is relative to N4835.

> > [Drafting Note: LWG 3340 has considerable wording overlap with this issue. If LWG 3336 is applied at the same meeting or later than LWG 3340, please refer to Option A in LWG 3340 as a guideline how to apply the merge.]

> 1. Before 20.20.5 [format.functions] insert a new sub-clause as indicated:

>    > 20.20.? Error reporting [format.err.report]

>    > -?- Formatting functions throw exceptions to report formatting and other errors. They throw `format_error` if an argument `fmt` is passed that is not a format string and propagate exceptions thrown by `formatter` specializations and iterator operations. Failure to allocate storage is reported by throwing an exception as described in 16.4.6.13 [res.on.exception.handling].

> 2. Modify 20.20.5 [format.functions] as indicated:

>    >     string vformat(string_view fmt, format_args args);
>    >     wstring vformat(wstring_view fmt, wformat_args args);
>    >     string vformat(const locale& loc, string_view fmt, format_args args);
>    >     wstring vformat(const locale& loc, wstring_view fmt, wformat_args args);

>    > > -6- […]

>    > > -7- Throws: `format_error` if `fmt` is not a format string As specified in 20.20.3 [format.err.report].

>    > […]

>    >     template<class Out>
>    >       Out vformat_to(Out out, string_view fmt, format_args_t<Out, char> args);
>    >     template<class Out>
>    >       Out vformat_to(Out out, wstring_view fmt, format_args_t<Out, wchar_t> args);
>    >     template<class Out>
>    >       Out vformat_to(Out out, const locale& loc, string_view fmt,
>    >                      format_args_t<Out, char> args);
>    >     template<class Out>
>    >       Out vformat_to(Out out, const locale& loc, wstring_view fmt,
>    >                      format_args_t<Out, wchar_t> args);

>    > > […]

>    > > -15- Throws: `format_error` if `fmt` is not a format string As specified in 20.20.3 [format.err.report].

>    > […]

>    >     template<class Out, class... Args>
>    >       format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
>    >                                           string_view fmt, const Args&... args);
>    >     template<class Out, class... Args>
>    >       format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
>    >                                           wstring_view fmt, const Args&... args);
>    >     template<class Out, class... Args>
>    >       format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
>    >                                           const locale& loc, string_view fmt,
>    >                                           const Args&... args);
>    >     template<class Out, class... Args>
>    >       format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
>    >                                           const locale& loc, wstring_view fmt,
>    >                                           const Args&... args);

>    > > […]

>    > > -21- Throws: `format_error` if `fmt` is not a format string As specified in 20.20.3 [format.err.report].

>    > […]

>    >     template<class... Args>
>    >       size_t formatted_size(string_view fmt, const Args&... args);
>    >     template<class... Args>
>    >       size_t formatted_size(wstring_view fmt, const Args&... args);
>    >     template<class... Args>
>    >       size_t formatted_size(const locale& loc, string_view fmt, const Args&... args);
>    >     template<class... Args>
>    >       size_t formatted_size(const locale& loc, wstring_view fmt, const Args&... args);

>    > > […]

>    > > -25- Throws: `format_error` if `fmt` is not a format string As specified in 20.20.3 [format.err.report].

[2020-02-12, Prague; LWG discussion]

Resolved by LWG 3340.

Proposed resolution:

Resolved by LWG 3340.