4078. What if arguments alias the output buffer in std::format_to?

Section: 28.5.5 [format.functions] Status: New Submitter: Jan Schultke Opened: 2024-04-24 Last modified: 2024-04-27

Priority: Not Prioritized

View all other issues in [format.functions].

View all issues with New status.

Discussion:

int main() {
  int x = 12345;
  // note: this is "awoo" followed by 28 zeros (9.4.3 [dcl.init.string] p3)
  char buffer[32] = "awoo";
  std::format_to(buffer, "{}{}", x, buffer);
  std::println("{}", buffer);
}

The output of this code is unspecified to be either "1234512345" or "12345awoo", where GCC currently outputs the former. Formatting occurs through function calls (see 28.5.6.4 [format.formatter.spec] p1) and those cannot be unsequenced, however, it's also nowhere stated in what order the arguments get formatted and how the output iterator is advanced between calls to the formatters.

The status quo is undesirable because unspecified formatting output is not useful to the user, and the lack of a precondition which would forbid aliasing between arguments and the output buffer restricts the implementation.

My intuition is to add Preconditions specifications to functions in 28.5.5 [format.functions] which would forbid the output range of the output iterator to overlap ranges of the arguments.

A friend of mine has suggested to add a Preconditions to the BasicFormatter requirements instead, dealing with the issue at the root (f.format(u, fc)).

Proposed resolution: