C++ Logo


Advanced search

Internal fill *not* considered harmful (re: P1652)

From: Matthew Woehlke <mwoehlke.floss_at_[hidden]>
Date: Tue, 25 Jun 2019 12:46:49 -0400
(Sigh, now *I'm* sending mail to the old list by accident... re-send to
the new list...)

(Should this sort of comment be raised on the github issue, instead,
these days? Is there an expectation how discussion on github issues that
correspond to papers should be used? Also, someone may want to forward
this to the internal LEWG reflector, to which I am not subscribed and
don't have the address...)

Looking at the C++-targeted papers, I noticed that P1652 proposes
removing the '=' alignment specifier, citing this problematic use case:

  std::string s1 = std::format("{:0=6}", nan); // s1 == "000nan"

However, I don't think this is a problem; it is doing exactly what the
code author asked. In particular, note:

  std::string s1 = std::format("{:%=6}", -inf); // s1 == "-**inf"
  std::string s1 = std::format("{:%=+6}", inf); // s1 == "+**inf"

I think the problem is really with P0645's statement: "This is
equivalent to a fill character of '0' with an alignment type of '='."

It isn't internal alignment that is the problem, it's treating the
special case of width.starts_with('0') as equivalent to '0=':

  std::string s2 = std::format("{:06}", nan); // s2 == "000nan"; bad!

P1652 *correctly* proposes to make this follow C99:

  std::string s2 = std::format("{:06}", nan); // s2 == " nan"

However, this also illustrates that fill and arithmetic zero-padding
aren't precisely the same thing and shouldn't be conflated. In
particular, IMHO the following would be correct behavior:

  std::string s2 = std::format("{:*<06}", 123); // s2 == "000123"
  std::string s2 = std::format("{:*<06}", nan); // s2 == "***nan"

I won't be at Cologne (hoping to make Belfast though), but I hope folks
will consider fixing this feature rather than nuking it entirely because
a related feature was (mis)specified in terms of it.

Instead, I would humbly suggest the following wording:

  Preceding the width field by a zero ('0') character pads leading zeros
  (following any indication of sign or base) to the field width, except
  when applying to an infinity or NaN. This option is only valid for
  arithmetic types other than charT and bool or when an integer
  presentation type is specified. If the ‘0’ and an align option both
  appear, **this padding is applied prior to any other alignment and

(Emphasis indicates changes vs. P1652's proposed wording.)


Received on 2019-06-25 11:48:43