C++ Logo

sg16

Advanced search

Re: [isocpp-sg16] P3904 -- When paths go WTF: making formatting lossless this Wednesday 7/22

From: Tom Honermann <tom_at_[hidden]>
Date: Mon, 3 Aug 2026 20:56:05 -0400
My apologies for missing the meeting. Thanks to Victor for passing his
presentation slides on to me; they are now attached to the wiki page.

The paper and presentation slides reveal a (totally understandable and
unsurprising) bias; they claim that there is only one case where
formatted paths don't losslessly round-trip, but that is not correct.
The slides concentrate on char-based formatting of
wchar_t-based paths (with char-based paths on POSIX as a comparison
point) , but doesn't consider wchar_t-based formatting of char-based
paths. The latter case won't preserve lossless round-tripping either.
Consider the following example:

    #include <filesystem>
    #include <format>
    int main() {
    std::filesystem::path p("\x80");
    std::wstring ws = std::format(L"{}", p);
    }

Curiously libc++, libstdc++, and MSSTL all reject that example.
https://godbolt.org/z/G1vbrxrqT.

My reading of the standard is that this example is well-formed with
implementation-defined transcoding ([fs.path.fmtr.funcs]p5
<https://eel.is/c++draft/fs.path.fmtr#funcs-5>) which, of course,
doesn't guarantee much of anything.

    template<class FormatContext>
       typename FormatContext::iterator
         format(const filesystem::path& p, FormatContext& ctx) const;

    /Effects/: Let s be
    p.generic_string<filesystem​::​path​::​value_type>() if the g option
    is used, otherwise p.native(). Writes s into ctx.out(), adjusted
    according to the /path-format-spec/. If charT is char,
    path​::​value_type is wchar_t, and the literal encoding is UTF-8,
    then the escaped path is transcoded from the native encoding for
    wide character strings to UTF-8 with maximal subparts of ill-formed
    subsequences substituted with U+FFFD replacement character per the
    Unicode Standard, Chapter 3.9 U+FFFD Substitution in Conversion. If
    charT and path​::​value_type are the same then no transcoding is
    performed. *Otherwise, transcoding is implementation-defined.*

To be clear, I expect approximately nobody to be concerned about the
inability to losslessly round-trip paths through wchar_t on POSIX
systems. But technically, the claims in the paper about lone surrogate
code points in Windows paths being the only case where paths don't
losslessly round-trip is incorrect.

Tom.

On 8/3/26 12:01 AM, Tom Honermann via SG16 wrote:
>
> Minutes for this meeting have been posted to the wiki here
> <https://wiki.isocpp.org/2026_Telecons:SG16Teleconference2026-07-22>.
> For those that attended, please review and suggest corrections.
>
> Tom.
>
> On 7/21/26 6:53 AM, Steve Downey via SG16 wrote:
>> We will review Victor's paper P3904 tomorrow.
>>
>> https://iso.zoom.us/j/98307328424
>>
>>
>>
>

Received on 2026-08-04 00:56:08