Date: Wed, 11 Mar 2026 12:57:52 -0400
On 3/10/26 7:24 PM, Hubert Tong wrote:
> On Tue, Mar 10, 2026 at 4:11 PM Tom Honermann via SG16
> <sg16_at_[hidden]> wrote:
>
> SG16 will hold a meeting *tomorrow*, Wednesday, March 11th, at
> 19:30 UTC (timezone conversion
> <https://www.timeanddate.com/worldclock/converter.html?iso=20260311T193000&p1=1440&p2=tz_pdt&p3=tz_mdt&p4=tz_cdt&p5=tz_edt&p6=tz_cet>).
>
> *Note that daylight savings time has started in North America, so
> this meeting will start one hour later relative to the local time
> of our previous meeting. There is no local time difference for
> those attending from Europe.*
>
> The agenda is:
>
> * P3412R3: String interpolation <https://wg21.link/p3412r3>.
> * D3951R1: String Interpolation with Template Strings
> <https://isocpp.org/files/papers/D3951R1.html>.
>
> We began review of these proposals during the 2026-02-25 SG16
> meeting
> <https://wiki.isocpp.org/2026_Telecons:SG16Teleconference2026-02-25>,
> but did not conclude discussion (we reviewed an earlier revision
> of P3412R1 <https://wg21.link/p3412r1> during the 2025-02-26 SG16
> meeting
> <https://wiki.isocpp.org/2025_Telecons:SG16Teleconference2025-02-26>
> a year ago). D3951R1 remains a draft revision, but was updated
> since our last meeting to include support for UDLs; see section
> 3.10, "Support for User-Defined Literals"
> <https://isocpp.org/files/papers/D3951R1.html#support-for-user-defined-literals>.
>
> Discussion in our last meeting suggested an emerging preference
> for the lambda-like synthesis of an unnamed type model proposed by
> D3951R1 over the __format__ mechanism of P3412R3. The
> representation of interpolated strings is not a core SG16 concern,
> but it is relevant to other concerns that we should be expected to
> provide guidance on. For example, whether the selected model
> should be amenable to support for other formatting facilities such
> as printf() or logging frameworks. Both proposals discuss support
> for printf() via translation of a std::format-like
> /format-specifier/ field, but other options are possible. For
> example, the /format specifier/ could allow the specifiers to be
> context dependent; e.g., std::printf(f"{name:%s}\n"). The details
> of how such support might be provided are not so important right
> now, but it would be helpful to provide direction on whether these
> proposals should be extensible to printf() and other formatting
> facilities.
>
> Thanks Tom for organizing.
>
> Candidate polls:
>
> * Poll: Interpolated strings should be usable as the format
> argument to std::printf().
>
> During the discussion, is there anyone who will champion this? At a
> minimum, there needs to be recorded rationale; for example, to support
> limited runtime environments that have printf-like facilities.
I don't know about a champion for this. The poll is intended to ask
whether SG16 feels it is important to support printf() in some manner.
>
> * Poll: Interpolated strings should be consumable by arbitrary
> formatting facilities.
>
> IMO, this poll is too vague as to the ergonomics of the "consumability".
It is vague. That was intentional. The idea is to ask if the feature
should be sufficiently general to be adaptable to facilities not defined
by the standard.
>
> An additional candidate poll is:
> Poll: Interpolated strings should be usable in C-like C++ code in
> contexts suitable for pure C (if C were to have interpolated strings).
I agree, that is another good candidate poll.
>
> Full support for std::format(), std::print(), and std::printf()
> requires support for char and the L (wchar_t) encoding prefix. It
> would be helpful to establish guidance for support of the other
> encoding prefixes and character types. Candidate polls:
>
> * Poll: The u8 (char8_t) encoding prefix should be supported.
> * Poll: The u (char16_t) encoding prefix should be supported.
> * Poll: The U (char32_t) encoding prefix should be supported.
>
> Previous discussion has concerned lexing of interpolated strings,
> but we haven't established positions on how alternate tokens,
> digraphs, UCNs, escape sequences, and UDLs should be handled,
> particularly with regard to support for raw-string literals.
>
> I believe we got presentations, but I don't recall the group adopting
> a lexing approach.
Correct, we haven't. The first poll below was intended to ascertain
consensus for a lexing approach.
>
> Consider fR"xxx({foo(*u8'\t'*)})xxx". Is the expression
> well-formed because \t denotes the tab character or is it
> ill-formed because multicharacter literals cannot have an encoding
> prefix? If the latter, can string literal concatenation be used to
> avoid the problem? e.g., fR"xxx({foo()xxx" *"u8'\t'"*
> R"xxx()})xxx"? If so, does concatenation within an extraction
> field create implementation challenges? Candidate polls:
>
> * Poll: Lexing of interpolated strings should scan for
> characters within extraction fields (not tokens; e.g., :: is
> two colon characters, not the scope resolution operator).
> * Poll: Extraction fields may span concatenated string literals
> (e.g., f"{" "name" "}").
> * Poll: Alternate tokens and digraphs behave the same as their
> primary token when present in an extraction field (but not in
> the literal portions of the interpolated string).
> * Poll: UCNs may not designate members of the basic character
> set when present in an extraction field (but may in the
> literal portions of the (non-raw) interpolated string or in a
> nested literal).
> * Poll: Escape sequences (simple, numeric, and conditional) are
> not processed as escape sequences when present in an
> extraction field (e.g., they are initially treated as in raw
> string literals, but may act as an escape sequence in a nested
> literal).
>
> I would prefer to ask whether an interpolated string is "string first"
> (whose string value is then processed to identify extraction fields
> which may contain text that will be pp-tokenized) or a piecewise
> construct (where extraction fields contain pp-tokens).
> Especially for the second poll, the two models generate different,
> valid interpretations of
> f"{" "name" "}"
>
> 1. name is the sole pp-token in the extraction field.
> 2. The extraction token consists of three pp-tokens: " ", name, and " ".
>
Interesting. My expectation has been aligned with the first case, but
the latter (I think) has the nice property of avoiding potentially
recursive macro expansion. Consider:
constexpr char MACRO[] = "ORCAM";
#define MACRO "MACRO"
f"{" MACRO "}"
MACRO must be initially expanded to allow string literal concatenation
to occur. The question is then whether MACRO is expanded again to
produce the "MACRO" pp-token for the field replacement thus formatting
MACRO as a string, or whether the MACRO pp-token then designates the
identifier for the declared variable thus formatting ORCAM as a string.
If recursive macro expansion were to be allowed, then I think this
would generate infinite recursion. That seems undesirable.
#define MACRO f"{MACRO}"
MACRO
> I also have qualms about allowing extraction fields in raw strings
> without the involvement of the d-char-sequence.
> In particular, I am against having the "outer raw string" end later
> than the first instance of )abcdef" in the following:
> fR"abcdef(
> {R"abcdef()abcdef"}
> abcdef)"
>
> I would be okay with
> fR"abcdef(
> abcdef{R"abcdef()abcdef"}abcdef
> abcdef)"
Those are good considerations, thank you.
Tom.
>
> -- HT
> On Tue, Mar 10, 2026 at 4:11 PM Tom Honermann via SG16
> <sg16_at_[hidden]> wrote:
>
> SG16 will hold a meeting *tomorrow*, Wednesday, March 11th, at
> 19:30 UTC (timezone conversion
> <https://www.timeanddate.com/worldclock/converter.html?iso=20260311T193000&p1=1440&p2=tz_pdt&p3=tz_mdt&p4=tz_cdt&p5=tz_edt&p6=tz_cet>).
>
> *Note that daylight savings time has started in North America, so
> this meeting will start one hour later relative to the local time
> of our previous meeting. There is no local time difference for
> those attending from Europe.*
>
> The agenda is:
>
> * P3412R3: String interpolation <https://wg21.link/p3412r3>.
> * D3951R1: String Interpolation with Template Strings
> <https://isocpp.org/files/papers/D3951R1.html>.
>
> We began review of these proposals during the 2026-02-25 SG16
> meeting
> <https://wiki.isocpp.org/2026_Telecons:SG16Teleconference2026-02-25>,
> but did not conclude discussion (we reviewed an earlier revision
> of P3412R1 <https://wg21.link/p3412r1> during the 2025-02-26 SG16
> meeting
> <https://wiki.isocpp.org/2025_Telecons:SG16Teleconference2025-02-26>
> a year ago). D3951R1 remains a draft revision, but was updated
> since our last meeting to include support for UDLs; see section
> 3.10, "Support for User-Defined Literals"
> <https://isocpp.org/files/papers/D3951R1.html#support-for-user-defined-literals>.
>
> Discussion in our last meeting suggested an emerging preference
> for the lambda-like synthesis of an unnamed type model proposed by
> D3951R1 over the __format__ mechanism of P3412R3. The
> representation of interpolated strings is not a core SG16 concern,
> but it is relevant to other concerns that we should be expected to
> provide guidance on. For example, whether the selected model
> should be amenable to support for other formatting facilities such
> as printf() or logging frameworks. Both proposals discuss support
> for printf() via translation of a std::format-like
> /format-specifier/ field, but other options are possible. For
> example, the /format specifier/ could allow the specifiers to be
> context dependent; e.g., std::printf(f"{name:%s}\n"). The details
> of how such support might be provided are not so important right
> now, but it would be helpful to provide direction on whether these
> proposals should be extensible to printf() and other formatting
> facilities.
>
> Thanks Tom for organizing.
>
> Candidate polls:
>
> * Poll: Interpolated strings should be usable as the format
> argument to std::printf().
>
> During the discussion, is there anyone who will champion this? At a
> minimum, there needs to be recorded rationale; for example, to support
> limited runtime environments that have printf-like facilities.
I don't know about a champion for this. The poll is intended to ask
whether SG16 feels it is important to support printf() in some manner.
>
> * Poll: Interpolated strings should be consumable by arbitrary
> formatting facilities.
>
> IMO, this poll is too vague as to the ergonomics of the "consumability".
It is vague. That was intentional. The idea is to ask if the feature
should be sufficiently general to be adaptable to facilities not defined
by the standard.
>
> An additional candidate poll is:
> Poll: Interpolated strings should be usable in C-like C++ code in
> contexts suitable for pure C (if C were to have interpolated strings).
I agree, that is another good candidate poll.
>
> Full support for std::format(), std::print(), and std::printf()
> requires support for char and the L (wchar_t) encoding prefix. It
> would be helpful to establish guidance for support of the other
> encoding prefixes and character types. Candidate polls:
>
> * Poll: The u8 (char8_t) encoding prefix should be supported.
> * Poll: The u (char16_t) encoding prefix should be supported.
> * Poll: The U (char32_t) encoding prefix should be supported.
>
> Previous discussion has concerned lexing of interpolated strings,
> but we haven't established positions on how alternate tokens,
> digraphs, UCNs, escape sequences, and UDLs should be handled,
> particularly with regard to support for raw-string literals.
>
> I believe we got presentations, but I don't recall the group adopting
> a lexing approach.
Correct, we haven't. The first poll below was intended to ascertain
consensus for a lexing approach.
>
> Consider fR"xxx({foo(*u8'\t'*)})xxx". Is the expression
> well-formed because \t denotes the tab character or is it
> ill-formed because multicharacter literals cannot have an encoding
> prefix? If the latter, can string literal concatenation be used to
> avoid the problem? e.g., fR"xxx({foo()xxx" *"u8'\t'"*
> R"xxx()})xxx"? If so, does concatenation within an extraction
> field create implementation challenges? Candidate polls:
>
> * Poll: Lexing of interpolated strings should scan for
> characters within extraction fields (not tokens; e.g., :: is
> two colon characters, not the scope resolution operator).
> * Poll: Extraction fields may span concatenated string literals
> (e.g., f"{" "name" "}").
> * Poll: Alternate tokens and digraphs behave the same as their
> primary token when present in an extraction field (but not in
> the literal portions of the interpolated string).
> * Poll: UCNs may not designate members of the basic character
> set when present in an extraction field (but may in the
> literal portions of the (non-raw) interpolated string or in a
> nested literal).
> * Poll: Escape sequences (simple, numeric, and conditional) are
> not processed as escape sequences when present in an
> extraction field (e.g., they are initially treated as in raw
> string literals, but may act as an escape sequence in a nested
> literal).
>
> I would prefer to ask whether an interpolated string is "string first"
> (whose string value is then processed to identify extraction fields
> which may contain text that will be pp-tokenized) or a piecewise
> construct (where extraction fields contain pp-tokens).
> Especially for the second poll, the two models generate different,
> valid interpretations of
> f"{" "name" "}"
>
> 1. name is the sole pp-token in the extraction field.
> 2. The extraction token consists of three pp-tokens: " ", name, and " ".
>
Interesting. My expectation has been aligned with the first case, but
the latter (I think) has the nice property of avoiding potentially
recursive macro expansion. Consider:
constexpr char MACRO[] = "ORCAM";
#define MACRO "MACRO"
f"{" MACRO "}"
MACRO must be initially expanded to allow string literal concatenation
to occur. The question is then whether MACRO is expanded again to
produce the "MACRO" pp-token for the field replacement thus formatting
MACRO as a string, or whether the MACRO pp-token then designates the
identifier for the declared variable thus formatting ORCAM as a string.
If recursive macro expansion were to be allowed, then I think this
would generate infinite recursion. That seems undesirable.
#define MACRO f"{MACRO}"
MACRO
> I also have qualms about allowing extraction fields in raw strings
> without the involvement of the d-char-sequence.
> In particular, I am against having the "outer raw string" end later
> than the first instance of )abcdef" in the following:
> fR"abcdef(
> {R"abcdef()abcdef"}
> abcdef)"
>
> I would be okay with
> fR"abcdef(
> abcdef{R"abcdef()abcdef"}abcdef
> abcdef)"
Those are good considerations, thank you.
Tom.
>
> -- HT
Received on 2026-03-11 16:57:56
