C++ Logo

std-proposals

Advanced search

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

From: Victor Zverovich <victor.zverovich_at_[hidden]>
Date: Tue, 25 Jun 2019 12:03:50 -0700
All but one uses of `=` with Folly Format or {fmt} that I've seen
(including an extensive search in one of the biggest C++ codebases) could
have been rewritten in a simpler way with the `0` flag. The only case that
I've found where `=` was used with fill other than `0` was a Folly Format
test case.

Do you have any use case for `=` that you cannot express by other means?

The `=` alignment in P0645 comes from Python where it's pretty broken:

>>> "{: =+#8x}".format(4)
  '+0x 4'

AFAICS it was just a failed attempt to generalize `0` in
https://www.python.org/dev/peps/pep-3101/

'=' - Forces the padding to be placed after the sign (if any)
> but before the digits. This is used for printing fields
> in the form '+000000120'. ...
>

- Victor


On Tue, Jun 25, 2019 at 8:48 AM Matthew Woehlke <mwoehlke.floss_at_[hidden]>
wrote:

> (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
> filling.**
>
> (Emphasis indicates changes vs. P1652's proposed wording.)
>
> --
> Matthew
>

Received on 2019-06-25 14:05:52