Title
format-arg-store::args is unintentionally not exposition-only
Status
c++23
Section
[format.arg.store]
Submitter
Casey Carter

Created on 2021-04-22.00:00:00 last changed 4 months ago

Messages

Date: 2021-06-07.16:58:04

Proposed resolution:

This wording is relative to N4885.

  1. Modify [format.syn], header <format> synopsis, as indicated:

    […]
    // [format.arg.store], class template format-arg-store
    template<class Context, class... Args> structclass format-arg-store; // exposition only
    
    template<class Context = format_context, class... Args>
      format-arg-store<Context, Args...>
        make_format_args(const Args&... fmt_args);
    […]
    
  2. Modify [format.arg.store] as indicated:

    namespace std {
      template<class Context, class... Args>
      structclass format-arg-store { // exposition only
        array<basic_format_arg<Context>, sizeof...(Args)> args; // exposition only
      };
    }
    

    -1- An instance of format-arg-store stores formatting arguments.

    template<class Context = format_context, class... Args>
      format-arg-store<Context, Args...> make_format_args(const Args&... fmt_args);
    

    -2- Preconditions: The type typename Context::template formatter_type<Ti> meets the Formatter requirements ([formatter.requirements]) for each Ti in Args.

    -3- Returns: An object of type format-arg-store<Context, Args...> whose args data member is initialized with {basic_format_arg<Context>(fmt_args)...}.

Date: 2021-06-07.00:00:00

[ 2021-06-07 Approved at June 2021 virtual plenary. Status changed: Voting → WP. ]

Date: 2021-05-15.00:00:00

[ 2021-05-20; Reflector poll ]

Set status to Tentatively Ready after six votes in favour during reflector poll.

Date: 2021-05-15.00:00:00

[ 2021-05-18; Tim updates wording. ]

Date: 2021-05-15.00:00:00

[ 2021-05-10; Reflector poll ]

Priority set to 3. Tim: "The current specification of make_format_args depends on format-arg-store being an aggregate, which is no longer true with this PR."

Previous resolution [SUPERSEDED]:

This wording is relative to N4885.

  1. Modify [format.syn], header <format> synopsis, as indicated:

    […]
    // [format.arg.store], class template format-arg-store
    template<class Context, class... Args> structclass format-arg-store; // exposition only
    […]
    
  2. Modify [format.arg.store] as indicated:

    namespace std {
      template<class Context, class... Args>
      structclass format-arg-store { // exposition only
        array<basic_format_arg<Context>, sizeof...(Args)> args; // exposition only
      };
    }
    
Date: 2021-04-22.00:00:00

Despite the statement in [format.args]/1:

An instance of basic_format_args provides access to formatting arguments. Implementations should optimize the representation of basic_format_args for a small number of formatting arguments. [Note 1: For example, by storing indices of type alternatives separately from values and packing the former. — end note]

make_format_args and make_wformat_args are specified to return an object whose type is a specialization of the exposition-only class template format-arg-store which has a public non-static data member that is an array of basic_format_arg. In order to actually "optimize the representation of basic_format_args" an implementation must internally avoid using make_format_args (and make_wformat_args) and instead use a different mechanism to type-erase arguments. basic_format_args must still be convertible from format-arg-store as specified, however, so internally basic_format_args must support both the bad/slow standard mechanism and a good/fast internal-only mechanism for argument storage.

While this complicated state of affairs is technically implementable, it greatly complicates the implementation of <format> with no commensurate benefit. Indeed, naive users may make the mistake of thinking that e.g. vformat(fmt, make_format_args(args...)) is as efficient as format(fmt, args...) — that's what the "Effects: Equivalent to" in [format.functions]/2 implies — and inadvertently introduce performance regressions. It would be better for both implementers and users if format-arg-store had no public data members and its member args were made exposition-only.

History
Date User Action Args
2023-11-22 15:47:43adminsetstatus: wp -> c++23
2021-06-07 16:58:04adminsetmessages: + msg11909
2021-06-07 16:58:04adminsetstatus: voting -> wp
2021-05-26 21:11:22adminsetstatus: ready -> voting
2021-05-20 08:53:38adminsetmessages: + msg11827
2021-05-20 08:53:38adminsetstatus: new -> ready
2021-05-18 13:50:07adminsetmessages: + msg11816
2021-05-10 16:30:18adminsetmessages: + msg11797
2021-04-24 16:31:28adminsetmessages: + msg11783
2021-04-22 00:00:00admincreate