3242. std::format: missing rules for arg-id in width and precision

Section: 28.5.2.2 [format.string.std] Status: C++20 Submitter: Richard Smith Opened: 2019-07-31 Last modified: 2021-02-25

Priority: 1

View other active issues in [format.string.std].

View all other issues in [format.string.std].

View all issues with C++20 status.

Discussion:

According to 28.5.2 [format.string] we have:

If the numeric arg-ids in a format string are 0, 1, 2, ... in sequence, they can all be omitted (not just some) and the numbers 0, 1, 2, ... will be automatically used in that order. A format string does not contain a mixture of automatic and manual indexing.

… but what does that mean in the presence of arg-id in width and precision? Can one replace

"{0:{1}} {2}"

with

"{:{}} {}"

? The grammar says the answer is no, because the arg-id in width is not optional, but the normative wording says the answer is yes.

Victor Zverovich:

That's a bug in the grammar. The arg-id should be optional in width and precision:

width     ::= nonzero-digit [integer] | '{' [arg-id] '}'
precision ::= integer | '{' [arg-id] '}'

[2020-02 Status to Immediate on Thursday morning in Prague.]

Proposed resolution:

This wording is relative to N4830.

  1. Modify the width and precision grammar in the syntax of format specifications of 28.5.2.2 [format.string.std] as indicated:

    […]
    width:
             positive-integer
             { arg-idopt }
    precision:
             . nonnegative-integer  
             . { arg-idopt }   
    […]         
    
  2. Modify 28.5.2.2 [format.string.std] as indicated:

    -6- The # option causes […]

    -?- If { arg-idopt } is used in a width or precision, the value of the corresponding formatting argument is used in its place. If the corresponding formatting argument is not of integral type, or its value is negative for precision or non-positive for width, an exception of type format_error is thrown.

    -7- The positive-integer in width is a decimal integer defining the minimum field width. If width is not specified, there is no minimum field width, and the field width is determined based on the content of the field.