1. Executive summary
We have not met in-person since the February 2020 meeting in Prague because of the global pandemic. Weâre instead holding weekly teleconferences, as detailed in [P2145R1]. We focus on providing non-final guidance, and will use electronic straw polls as detailed in [P2195R0] to move papers and issues forward in a asynchronous manner.
Our main achievements have been:
-
Issue processing: most of the 50 language evolution issues have proposed resolutions, and a large number of them have been voted on through electronic polling.
-
C++23: weâve started work on papers for C++23 and later.
-
Incubation: weâve acted as EWG-I and "incubated" some early papers by providing early feedback to authors.
This paper outlines:
-
The work achieved;
-
Other ongoing work;
-
Lists the straw polls that were submitted for the February 2021 polling period as well as their results;
-
Lists the remaining outstanding issues.
2. Paper of note
-
[P1000R4] C++ IS schedule
-
[P0592R4] To boldly suggest an overall plan for C++23
-
[P1999R0] Process: double-check evolutionary material via a Tentatively Ready status
-
[P2195R0] Electronic Straw Polls
-
[P2145R1] Evolving C++ Remotely
3. Tentatively ready papers
Following our process in [P1999R0], we usually mark papers as tentatively ready for CWG. We would usually take a brief look at the next meeting, and if nothing particular concerns anyone, send them to CWG. However, given the pandemic, weâve decided to provide guidance only in virtual teleconferences, and have an asynchronous polling mechanism to officially send papers to CWG or other groups as detailed in [P2195R0].
You can follow the lists of papers on GitHub:
4. Issue Processing
Weâve reviewed 50 Language Evolution issues at the Core groups' request, and have tentative resolutions for most. We donât want to poll all of these at the same time, and therefore only polled a subset in the February 2021 polling period, reserving other issues for later polling periods. Weâve will therefore only poll the "tentatively ready" issues (since theyâre tied to papers, and polled with said papers, as outlined below), as well as the "resolved" issues since telecon attendees believe that prior work has already addressed the issues.
§âŻ8 Remaining Open Issues contains a list of issues which arenât being voted on in this polling period.
5. Poll Results
In all, 36 people participated in the February 2021 EWG polls. Close to half of the voters were EWG regulars before the pandemic, the rest were CWG/LEWG/LWG/SG1/SG16 regulars, most have attended a good number of the EWG telecons regularly during the pandemic.
The list of polls which EWG took in the February 2021 polling period, along with their results, and some of the relevant comments from poll participants, are:
5.1. P2223R1 Trimming whitespaces before line splicing
-
Not yet seen by WG14, nor the SG22 C / C++ liaison group.
-
Highlight: make trailing whitespaces after
\
non-significant. -
đł Poll: Forward P2223R1 "Trimming whitespaces before line splicing" to Core, thereby also fixing [CWG1698].
Poll votes:
SF | F | N | A | SA |
11 | 15 | 4 | 0 | 0 |
Poll outcome: â consensus.
Salient comments:
- Strongly in favor as this aligns the standard with common practice, avoids contorting standard wording by implementations in order to claim conformance while producing the behavior programmers want, and avoids needless surprised and implementation divergence.
- We should not have implementation divergence on this, and this direction to resolve it is good.
- Iâm not particularly excited about this paper because it only partially solves the problem of implementation divergence in this space and does not outline a play to solve all the existing issues in a consistent way. This will not likely impact my users.
- Invisible differences in the behavior of code are bad.
- Reducing divergence in compilers is good.
- I find this somewhat unimportant.
5.2. P2201R0 Mixed string literal concatenation
-
Seen by WG14 as [N2594], straw Poll: Does the committee wish to adopt N2594 into C23 as is? 18-0-2 passes.
-
Highlight: string concatenation involving string-literals with encoding-prefixes mixing
L
,"" u8
,"" u
, and"" U
is currently conditionally-supported with implementation-defined behavior, this paper makes it ill-formed."" -
đł Poll: Forward P2201R0 "Mixed string literal concatenation" to Core, after adding an Annex C entry.
Poll votes:
SF | F | N | A | SA |
14 | 12 | 1 | 0 | 0 |
Poll outcome: â consensus.
Salient comments:
- This was meaningless and unimplemented. No good reason to have it.
- I was very horrified that we allowed this when I saw this paper for the first time.
- As paper said, this is not portable and without clear meaning.
- Implementation defined behavior that doesnât have many supporting implementations, PLUS can only result in nonsense needs to disappear from the language.
5.3. P2186R1 Removing Garbage Collection Support
-
Highlight: remove (not deprecate) garbage collection support in C++23.
-
đł Poll: Forward P2186R1 "Removing Garbage Collection Support" to Core.
Poll votes:
SF | F | N | A | SA |
12 | 12 | 4 | 1 | 0 |
Poll outcome: â consensus.
Salient comments:
- (Against) It does not seem to provide much harm, even if not used⊠And since the basic need seems genuine, Iâd prefer to keep the mechanism until it is properly handled, than removing it and having to reintroduce something similar later.
- Clearly, no need to have unused utilities.
- To the best of my knowledge, this is unused and not implemented in implementations. The specification cost of keeping it is not zero.
- Given that 10 years after being standardized, this is not provided in any major implementation, itâs IMHO save to assume that "nobody" needs this/can use this due to the issues outlined in the paper.
- Implementations of garbage collection exist, yet do not rely on the "garbage collection support" in the Standard. Furthermore, the paper argues convincingly that the Standardâs "support" for garbage collection does not support common use cases, like placement new in local arrays.
- Keeping stuff in the standard thatâs not supported and is lacking guidance for proper implementation makes little sense. Removing it might free space for a better, more useful specification thatâs not restricted to cmpatibility.
5.4. P2173R0 Attributes on Lambda-Expressions
-
Highlight: allow attributes for lambdas, those attributes appertaining to the function call operator of the lambda.
-
đł Poll: Forward P2173R0 "Attributes on Lambda-Expressions" to Core, thereby also fixing [CWG2097].
Poll votes:
SF | F | N | A | SA |
12 | 16 | 1 | 0 | 0 |
Poll outcome: â consensus.
Salient comments:
- This is a good addition because it makes lambdas more consistent with function call operators on named objects.
- The attributes are defined hereby to pertain to the correct entity, so that we will not have unfortunate consistency issues with other function attributes.
- I desperately need this functionality for multiple vendor-specific attributes.
- This fills a functionality gap and makes the language more regular.
5.5. P2156R1 Allow Duplicate Attributes
-
Seen by WG14 as [N2557], straw Poll: Is the committee in favor of adopting N2557 into C23? 19-0-0 passes.
-
Highlight: current limitations on duplicate attributes are inconsistent, this change removes all limitations on duplicate attributes in an attribute-list for all attributes that specify a limitation. This affects
,carries_dependency
,deprecated
,fallthrough
,likely
,unlikely
,unused
, andnoreturn
.no_unique_address -
đł Poll: Forward P2156R1 "Allow Duplicate Attributes" to Core, thereby also fixing [CWG1914].
Poll votes:
SF | F | N | A | SA |
12 | 11 | 3 | 1 | 1 |
Poll outcome: â consensus.
Salient comments:
- (Against / Strongly against) The use case (macro replacement) is questionable, especially for cases where the same attribute has different values. It also further complicates future extensions for reflection on attributes. We can resolved CWG1914 by declaring that the particular attributes mentioned there could not be specified more than once on a declaration, even in separate attribute specifiers.
- In practice, attributes are often hidden in macros and it is easy to get duplicates, and fixing the duplication is challenging in code that supports many compilers and standards.
- Especially useful for auto-generated code.
- It is easier on developers if we allow duplicate attributes.
- I see no reason for preventing
but allowing[[ X , X ]]
as these variants should be equivalent.[[ X ]] [[ X ]] - Compilers could still warn about duplicated attributes.
- This unifies the behavior with whatâs already been adopted into C.
- This makes the language more regular.
5.6. P2013R3 Freestanding Language: Optional :: operator new
-
Not yet seen by WG14, nor the SG22 C / C++ liaison group.
-
Highlight: on freestanding C++ implementations, make the various default allocating
optional. Placement:: operator new
is still required. Allnew
are still required. Hosted implementations are unchanged.:: operator delete -
đł Poll: Forward P2013R3 "Freestanding Language: Optional
" to Core.:: operator new
Poll votes:
SF | F | N | A | SA |
8 | 15 | 3 | 0 | 1 |
Poll outcome: â consensus.
Salient comments:
- (Strongly against) The freestanding implementation parts of the standard impact a very small number of users and the committee spends a disproportionally large amount of time with it. Iâm against any time spent on freestanding language work with the exception of its removal.
- Making freestanding more useful is a good thing.
- Consistent with C++ core principles to move errors to build time whenever possible.
- Matches existing practice.
- This is an important topic.
5.7. P1949R6 C++ Identifier Syntax using Unicode Standard Annex 31
-
C++20 NB comment NL029 05.10
-
Not yet seen by WG14, nor the SG22 C / C++ liaison group.
-
Highlight: C++11 uses a hand-curated list of Unicode codepoints to determine which characters are allowed in identifiers. This is flawed in many ways outlined in the paper. Replace this hand-curated list with the Unicode consortiumâs recommendations for identifiers [UAX31].
-
đł Poll: Forward P1949R6 "C++ Identifier Syntax using Unicode Standard Annex 31" to Core.
Poll votes:
SF | F | N | A | SA |
19 | 6 | 3 | 0 | 0 |
Poll outcome: â consensus.
Salient comments:
- The allow-list approach isnât sustainable. There are too many characters allowed that can be actively harmful, such as RTL modifiers.
- Follows Unicode recommendations. WG21 shouldnât be in the business of assigning meaning to Unicode characters, Unicode is authoritative in this case.
- Avoids surprising behavior that is difficult to defend.
- Good international language support encourages wider adoption and this wider adoption implies a larger global pool of resources for the development of the C++ ecosystem.
5.8. P1938R2 if consteval
-
C++20 NB comment FR22 20.15.10, discussed in Belfast
-
Highlight: C++20 added
andstd :: is_constant_evaluated ()
, which interact poorly with each other. This paper adds a new form ofconsteval
statement to address the poor interaction.if -
đł Poll: Forward P1938R2 "
" to Core.if consteval
Poll votes:
SF | F | N | A | SA |
20 | 7 | 2 | 0 | 0 |
Poll outcome: â consensus.
Salient comments:
- The number of experts who have been confused by
suggests that this is a much safer spelling for the utility.is_constant_evaluated - Makes metaprogramming more accessible and its code more readable, better composability.
- Sad that this wasnât in C++20.
5.9. P1847R3 Make declaration order layout mandated
-
Highlight: C++ currently lets compilers reorder data member layout if they have different access controls. Compilers donât take advantage of this permission. This paper removes the unused flexibility.
-
đł Poll: Forward P1847R3 "Make declaration order layout mandated" to Core.
Poll votes:
SF | F | N | A | SA |
12 | 7 | 7 | 1 | 2 |
Poll outcome: â consensus.
Chair comment on outcome: this was discussed in-person in Prague and Belfast and had strong consensus, the current objections had been discussed in person, and the request for finer-grained control are addressed in a separate paper (in fact, the paper was separated at WG21âs request).
Salient comments:
- (Against) Iâm mildly opposed to nailing down a property of the language that users should probably not depend on in the first place. I realize that the practical impact of doing so is small, but at the same time Iâm also not convinced by the benefits.
- (Strongly against) I think the current rules are sensible; they set aside a clearly delineated space for data that must remain layout-compatible over time. Access control is strongly associated with class invariants, whereas invariants canât be enforced on serialized data. It would not make sense to memcpy data from a file directly into the representation of a class type that maintains invariants. Instead, that data should be deserialized into a standard-layout struct, verified for conformance to invariants, and only then supplied to the class type after verification. The class type can use the standard-layout struct directly as a (private) class member. Iâve certainly seen plenty of code that assumes the rules in P1847 are already in place, thanks to compilers generally following those rules anyway, but I think such code is highly suspect and likely predicated on false assumptions about the validity of deserialized data. Iâd prefer that the language did not encourage writing more of this code.
- (Strongly against) I hate that some classes will have a standard, fixed layout, but that
is going to beis_standard_layout < T > false
for them (and for instance that common starting sequence will become a very hard to understand UB). Even if currently no well known implementation uses the allowed reordering, It seems that such reordering can provide structures with better packing, and an implementation might want to benefit from that eventually. So unless there is another mechanism to mean : Please, compiler, do what you think is best, I donât really see the point of removing this freedom. - Standardizing existing practice for an implementation freedom no one found a use for. It is what compilers have been doing for decades; we should be able to rely on it.
- The current layout rules are effectively frozen in this form by ABI compatibility concerns.
- Paves the way for the
attribute, which I would really like to see making progress.[[ layout (...)]]
5.10. P1401R4 Narrowing contextual conversions to bool
-
Addresses [CWG2320], which was caused by resolving [CWG2039], see Richard Smithâs email regarding this approach.
-
Highlight: allow conversions from integral types to type
inbool
andstatic_assert
-statements.if constexpr -
đł Poll: Forward P1401R4 "Narrowing contextual conversions to
" to Core.bool
Poll votes:
SF | F | N | A | SA |
13 | 13 | 3 | 0 | 0 |
Poll outcome: â consensus.
Salient comments:
- Increases consistency.
- The decision this paper is undoing is yet another example of an attempt to move the language in a particular direction, but without a complete migration plan. These incomplete migrations make the language incoherent and frustrating.
- I wish we could go the other direction and disallow any conversions to bool everywhere (including from integer and pointer types, regardless of context, allowing only user-defined conversions), but thereâs no way weâll ever get there from here. C++ is a language that thinks non-boolean types have boolean properties, and we shouldnât make exceptions to that based on context.
5.11. P1393R0 A General Property Customization Mechanism
-
Highlight: "properties" are a customization mechanism at the center of [P0443R14] executors. The proposed approach is library-only, but it could be possible to develop a language-based approach instead. The discussion and pollâs goal are to avoid a late-changing redesign of executors based on wanting a language-based approach for customization.
-
đł Poll: We understand properties and think that specifying them purely in library is the right approach.
Poll votes:
SF | F | N | A | SA |
1 | 4 | 14 | 4 | 2 |
Poll outcome: â no consensus, participants do not understand properties, and might want to specify executors' customizations mechanism as a language feature.
Salient comments:
- (Strongly against) I coauthored a paper that worked deeply with properties. I understood them when I was working with them, but my brain quickly pushed it all out of my head when I was done because they were so complex to work with. I do not think specifying them purely in library is the right approach.
- (Strongly against) properties are not understood. As one glaring example - there is no way to define a single polymorphic type to satisfy all the concepts listed as "applicable" for a property. several of the properties in 0443 expose this fault. Another example is how properties for values that can change at runtime run afoul of the equality behaviour defined for the polymorphic types. Authors of properties have been known to disagree on how to answer question about what properties are for and what they are not for. properties needs to be sent back to LEWG until a majority actually understand all the mechanisms in the properties paper and how they interact or until the mechanisms have been reduced to a set that is generally understood.
- (Against) I donât understand properties.
- Demanding a different solution at this late date, without offering any concrete alternative, would unnecessarily delay Executors, and would send authors a message that we donât value their time.
- The property system seems complicated, but that complication does not appear to arise from a lack of language support.
- Iâm not sure how Iâm supposed to understand properties if the papers donât explain it.
5.12. CWG2169 Narrowing conversions and overload resolution
- [CWG2169]
-
Current implementations ignore narrowing conversions during overload resolution, emitting a diagnostic if calling the selected function would involve narrowing. For example:
struct s { long m }; struct ss { short m ; }; void f ( ss ); void f ( s ); void g () { f ({ 1000000 }); // Ambiguous in spite of narrowing for f(ss) } However, the current wording of 12.4.3.1.5 [over.ics.list] paragraph 7 says,
Otherwise, if the parameter has an aggregate type which can be initialized from the initializer list according to the rules for aggregate initialization (9.4.1 [dcl.init.aggr]), the implicit conversion sequence is a user-defined conversion sequence with the second standard conversion sequence an identity conversion.
In the example above,
cannot be initialized fromss
because of the narrowing conversion, so presumably{ 1000000 }
should not be considered. If this is not the intended outcome, paragraph 7 should be restated in terms of having an implicit conversion sequence, as in, e.g., bullet 9.1, instead of a valid initialization.f ( ss ) - Notes 2020-04-29
- JFâs email to EWG 2020-10-19, with the follow-up suggestion that no paper was needed and CWG could resolve the issue if given guidance from EWG.
- đł Poll: Guidance to Core: implementations are right, the Standard needs to be fixed to address this issue by following existing implementations.
Poll votes:
SF | F | N | A | SA |
12 | 10 | 4 | 1 | 0 |
Poll outcome: â consensus.
Salient comments:
- (Against) I donât see the rationale for such a decision, and I would naively expect the sample code to compile.
- Standardize existing practice.
- We shouldnât need to look at a specific value that is passed in a call to determine what the overload being selected is.
5.13. CWG2355 Deducing noexcept-specifiers
-
The list of deducible forms in 13.10.2.5 [temp.deduct.type] paragraph 8 does not include the ability to deduce the value of the constant in a noexcept-specifier, although implementations appear to allow it. Note: multiple standard library implementations rely on it.
-
đł Poll: Guidance to Core: modify the Standard such that the value of a constant in a noexcept-specifier can be deduced.
Poll votes:
SF | F | N | A | SA |
11 | 13 | 2 | 0 | 0 |
Poll outcome: â consensus.
Salient comments:
- As stdlib implementations rely on it, we should change the standard to match.
- Fixes an obvious oversight.
5.14. CWG476 Determining the buffer size for placement new
-
Resolved by [CWG2382] (no overhead for placement
for arrays). CWG2382 was moved in Belfast as part of [P1969r0].new -
đł Poll: Mark CWG476 "Determining the buffer size for placement
" as resolved by P1969r0, and a duplicate of CWG2382.new
Poll votes:
SF | F | N | A | SA |
12 | 6 | 6 | 0 | 0 |
Poll outcome: â consensus.
Salient comments:
- The core issues already adopted have resolved this issue.
5.15. CWG687 template
keyword with unqualified-ids
-
Resolved by [P0846r0]
-
đł Poll: Mark CWG687 "
keyword with unqualified-ids" as resolved by P0846r0.template
Poll votes:
SF | F | N | A | SA |
12 | 9 | 5 | 0 | 0 |
Poll outcome: â consensus.
Salient comments:
- The paper in question was specifically presented to EWG as an alternative to the direction of this issue.
5.16. CWG1326 Deducing an array bound from an initializer-list
-
Resolved by [P0127R2] Declaring non-type
parameters withtemplate
, and [CWG1591].auto -
đł Poll: Mark CWG1326 "Deducing an array bound from an initializer-list" as resolved by P0127R2, and a duplicate of CWG1591.
Poll votes:
SF | F | N | A | SA |
11 | 10 | 6 | 0 | 0 |
Poll outcome: â consensus.
Salient comments:
- The core issues already adopted have resolved this issue.
5.17. CWG1331 const
mismatch with defaulted copy constructor
-
Resolved by [P0641r2] (whose title is Resolving Core Issue #1331, also resolves [CWG1426]).
-
đł Poll: Mark CWG1331 "
mismatch with defaulted copy constructor" as resolved by P0641r2.const
Poll votes:
SF | F | N | A | SA |
9 | 14 | 3 | 0 | 0 |
Poll outcome: â consensus.
Salient comments:
- The core issues already adopted have resolved this issue.
5.18. CWG1393 Pack expansions in using-declarations
-
Resolved by [P0195r2] (same title as issue)
-
đł Poll: Mark CWG1393 "Pack expansions in using-declarations" as resolved by P0195r2.
Poll votes:
SF | F | N | A | SA |
11 | 12 | 4 | 0 | 0 |
Poll outcome: â consensus.
Salient comments:
- The core issues already adopted have resolved this issue.
5.19. CWG1426 Allowing additional parameter types in defaulted functions
-
đł Poll: Mark CWG1426 "Allowing additional parameter types in defaulted functions" as resolved by P0641r2.
Poll votes:
SF | F | N | A | SA |
8 | 12 | 5 | 0 | 0 |
Poll outcome: â consensus.
Salient comments:
- The core issues already adopted have resolved this issue.
5.20. CWG1561 Aggregates with empty base classes
-
Resolved by [P0017r1] (which allowed aggregates to have base classes)
-
đł Poll: Mark CWG1561 "Aggregates with empty base classes" as resolved by P0017r1.
Poll votes:
SF | F | N | A | SA |
10 | 13 | 5 | 1 | 0 |
Poll outcome: â consensus.
Salient comments:
- (Against) The proposed change complicates aggregate initialization. I find that this goes against the trend of papers like P1008R1. More generally, I find that keeping aggregates simple encourages a more stateless, functional programming style.
- We chose a different path (which is more powerful if occasionally less convenient); thereâs nothing further to discuss here.
- Aggregates have problems and we do not have enough information to fix them right now. For example the symmetry between aggregates and structured bindings is missing. On the other hand, we can always reopen the issue or create a new one when new information appears.
5.21. CWG1912 exception-specification of defaulted function
-
The current rules requiring a defaulted member function to have an exception-specification compatible with that of the implicitly-declared function are overly constraining. It should be possible, for example, to specify that a defaulted move constructor will be non-throwing, based on knowledge available to the programmer, even if the implicitly-declared constructor would be throwing.
-
Resolved by [p1286r2]
-
đł Poll: Mark CWG1912 "exception-specification of defaulted function" as resolved by p1286r2.
Poll votes:
SF | F | N | A | SA |
10 | 12 | 6 | 0 | 0 |
Poll outcome: â consensus.
Salient comments:
- This issue has been argued completely: it is common practice to supply explicit exception-specifications at places where the compiler does not deduce the correct (or useful) setting.
- The solution is not worse than the alternatives. I do not like the "additional use case" with deliberately calling std::terminate. It is a trick that casual programmers will not understand.
5.22. CWG1931 Default-constructible and copy-assignable closure types
-
Resolved by [P0624r2] Default constructible and assignable stateless lambdas
-
đł Poll: Mark CWG1931 "Default-constructible and copy-assignable closure types" as resolved by P0624r2.
Poll votes:
SF | F | N | A | SA |
12 | 11 | 4 | 0 | 0 |
Poll outcome: â consensus.
Salient comments:
- The paper indeed resolves the issue.
5.23. CWG2295 Aggregates with deleted defaulted constructors
-
Should a class with a deleted non-user-provided default constructor be considered an aggregate?
-
Resolved by [P1008r1] Prohibit aggregates with user-declared constructors
-
đł Poll: Mark CWG2295 "Aggregates with deleted defaulted constructors" as resolved by P1008r1.
Poll votes:
SF | F | N | A | SA |
12 | 12 | 4 | 0 | 0 |
Poll outcome: â consensus.
Salient comments:
- The paper indeed resolves the issue.
5.24. CWG2341 Structured bindings with static
storage duration
-
Resolved by [P1091r3] Extending structured bindings to be more like variable declarations
-
đł Poll: Mark CWG2341 "Structured bindings with
storage duration" as resolved by P1091r3.static
Poll votes:
SF | F | N | A | SA |
11 | 12 | 4 | 0 | 0 |
Poll outcome: â consensus.
Salient comments:
- The paper indeed resolves the issue.
5.25. CWG2343 void *
non-type template parameters
-
According to 13.2 [temp.param] bullet 4.2, non-type template parameters of pointer type must be either pointer to object or pointer to function. This excludes
, which is an object pointer but not a pointer to object. However, most or all current implementations acceptvoid *
as a non-type template parameter. Notes from the April, 2018 Core teleconference: Not all implementations accept avoid *
template parameter, so this should not be a DR if it is eventually adopted. Furthermore, there is some implementation divergence over the kinds of template arguments that can be passed to avoid *
template parameter.void * -
Resolved by [P0732R2] (which used
in defining strong structural equality and used that for NTTPs) because [P0515R3] had givenstd :: strong_ordering
the type<=>
for "object pointers" (which includesstd :: strong_ordering
, even though void is not an object type). Later [P1907R1] replaced all that, saying simply that structural types (which include all scalar types) were acceptable, but that didnât changevoid *
's status. Davis emailed EWG the above text.void * -
đł Poll: Mark CWG2343 "
non-type template parameters" as resolved by P0732R2.void *
Poll votes:
SF | F | N | A | SA |
10 | 11 | 4 | 0 | 0 |
Poll outcome: â consensus.
Salient comments:
- The paper indeed resolves the issue.
5.26. CWG??? unqualified lookup in conversion-type-ids (Sent by Richard Smith to EWG, from CWG)
-
The basic situation looks like this:
struct A { struct B {}; operator B (); }; void f ( A a ) { a . operator B (); } There is a special-case lookup rule that allows this code to work: when looking up the
inB
, we look insidea . operator B ()
. Presumably the intent is to allowa
to be named in the same way when itâs referenced as it was named when it was declared. This is a fairly general rule: inoperator B
, we look up the< some context > operator B
in the same place in which we later look up the nameB
.operator B Question The issue we are facing is: exactly what lookups does the special-case rule apply to? Consider a few examples:
a . operator B < C > (); a . operator B D ::* (); a . operator decltype ( E )(); Which of
,B
,C
, andD
get the special "look this name up inE
" rule?a There is implementation divergence:
- Clang says none.
- EDG and MSVC say
only.B - GCC says
andB
.D - And the consistent rules weâre looking at now would say all of
,B
,C
, andD
are looked up inE
.A
- Resolved by [P1787R6].
- Notes 2020-10-28
- đł Poll: Mark the CWG issue sent by Richard Smith to EWG on 2020-06 "unqualified lookup in conversion-type-ids" as resolved by P1787R6.
Poll votes:
SF | F | N | A | SA |
9 | 10 | 5 | 0 | 0 |
Poll outcome: â consensus.
Salient comments:
- The paper indeed resolves the issue.
6. Polling Process
For each poll, participants are asked to vote one of:
-
Strongly in favor
-
In favor
-
Neutral
-
Against
-
Strongly against
Participants also have the option to abstain from voting on a particular poll. They are be asked to comment on each poll. This comment is mandatory, as it helps the chair determine consensus.
7. Teleconferences
Here are the minutes for the virtual discussions that were held since the Prague meeting in February 2020:
- 2020-04-09 Issue Processing
- 2020-04-15 Issue Processing
- 2020-04-23 Issue Processing
- 2020-04-29 Issue Processing
- 2020-05-07 Issue Processing
- 2020-05-13 Issue Processing
- 2020-05-21 A General Property Customization Mechanismâ[P1393R0] (P1393 tracking issue)
- 2020-06-10 Reviewing Deprecated Facilities of C++20 for C++23â[P2139R1] (P2139 tracking issue)
- 2020-06-18 C++ Identifier Syntax using Unicode Standard Annex 31â[P1949R4] (P1949 tracking issue)
- 2020-06-24 Extended floating-point types and standard namesâ[P1467R4] (P1467 tracking issue)
- 2020-07-02 Allow Duplicate Attributes, Attributes on Lambda-Expressionsâ[P2156R0] (P2156 tracking issue) and [P2173R0] (P2173 tracking issue)
- 2020-07-08 Pointer lifetime-end zap and provenance, tooâ[P1726R3] (P1726 tracking issue)
- 2020-07-16 Guaranteed copy elision for return variablesâ[P2025R1] (P2025 tracking issue)
- 2020-07-30 Reviewing Deprecated Facilities of C++20 for C++23, Removing Garbage Collection Supportâ[P2139R2] (P2139 tracking issue) and [P2186R0] (P2186 tracking issue)
- 2020-08-05 Transactional Memory Lite Support in C++â[P1875R0] (P1875 tracking issue)
- 2020-08-19 Freestanding Language: Optional
, Mixed string literal concatenationâ[P2013R2] (P2013 tracking issue) and [P2201R0] (P2201 tracking issue):: operator new - 2020-08-27 Exhaustiveness Checking for Pattern Matchingâ[P1371R3] (P1371 tracking issue)
- 2020-09-02
- a simple, scannable preprocessor-based resource acquisition methodâ[P1967R2] (P1967 tracking issue)#embed - 2020-09-10 A pipeline-rewrite operatorâ[P2011R1] (P2011 tracking issue)
- 2020-09-16 Pattern matching: inspect is always an expressionâ[P1371R3] (P1371 tracking issue)
- 2020-09-24 C++ Identifier Syntax using Unicode Standard Annex 31, Member Templates for Local Classesâ[P1949R6] (P1949 tracking issue) and [P2044R0] (P2044 tracking issue)
- 2020-09-30 Narrowing contextual conversions to bool, Generalized pack declaration and usageâ[P1401R3] (P1401 tracking issue) and [P1858R2] (P1858 tracking issue)
- 2020-10-08 Compound Literals,
â[P2174R0] (P2174 tracking issue) and [P1938R1] (P1938 tracking issue)if consteval - 2020-10-14 Inline Namespaces: Fragility Bites, Trimming whitespaces before line splicingâ[P1701R1] (P1701 tracking issue) and [P2223R0] (P2223 tracking issue)
- 2020-10-22 Issues Processing
- 2020-10-28 Issues Processing
- 2020-11-05 Deducing
âP0847R5 (P0847 tracking issue)this - 2020-11-19
in pattern matchinggoto - 2020-12-03
: decay-copy in the languageâP0849R5 (P0849 tracking issue)auto ( x ) - 2021-01-14 Polls
- 2021-01-20 Final polls preparation
- 2021-01-28 P2012 Fix the rangeâbased for loop
- 2021-02-03 P2280 Using unknown references in constant expressions
- 2021-02-11 P1974 Non-transient constexpr allocation using
propconst - 2021-02-17 P2242 Non-literal variables (and labels and
s) ingoto
functionsconstexpr - 2021-02-25 P1371 pattern matching: implementation experience pattern matching now has fairly capable prototype implementation and in this session it will be both demonstrated and described. Bruno, the core implementer, will also field any implementation related questions surrounding the proposal. See the Godbolt demo.
- 2021-03-02 P2279R0 We need a language mechanism for customization points joint EWG+LEWG session
8. Remaining Open Issues
The following table lists all remaining open issues referred to EWG by Core or Library. Some of them are ready to be polled but are held back from the February 2021 polling period to limit the number of polls in this round.
From |
# |
Title |
Notes |
Resolution |
Core |
Explicit instantiation of in-class |
A Note 2020-04-29 Tentative agreement: This should be well-formed. SF 1 F 10 N 2 A 1 SA 0Â JF emailed EWG / Core about this. Davis: the current name lookup approach which Core is taking in p1787 would disallow this. Supporting this is possible, it would be inconsistent, but would also be a feature. Notes 2020-10-22: wait until p1787 is voted into the working draft, because itâs making this behavior intentional. At that point, we can vote on marking the issue as Not a Defect. No objection to unanimous consent. |
â»ïž | |
Core |
Non- |
[Detailed description pending.] Hubert: question over the role of the For A userâs desire for wanting to suppress implicit instantiation can arise for different reasons: To reduce space in object files, executables, etc. and similarly to reduce the number of input symbols to the linker To reduce compile time in performing semantic analysis for instantiations whose definitions are provided elsewhere To control point-of-instantiation, avoiding contexts where the requisite declarations are not declared The special rule around inline functions allows Consider the following as a translation unit:
Marking the template definition The issue initially points out that this use of the I am not sure if CWG is asking EWG a specific question other than the general "we do not believe this is a wording or obvious consistency issue; is this an issue in terms of design?" Meeting: Hubert forked the thread on the reflector. Might want the education SG to take a look, or might want a paper. Meeting 2020-10-28: Inbal will try to put together the wording, to prove / disprove whether this is a defect. |
â»ïž | |
Lib |
initializer_list assignability |
std::initializer_list::operator= [support.initlist] is horribly broken and it needs deprecation: std::initializer_list<foo> a = {{1}, {2}, {3}}; a = {{4}, {5}, {6}}; // New sequence is already destroyed. Assignability of initializer_list isnât explicitly specified, but most implementations supply a default assignment operator. Iâm not sure what [description] says, but it probably doesnât matter. Proposed resolution: Edit [support.initlist] p1, class template initializer_list synopsis, as indicated: namespace std {   template<class E> class initializer_list {   public:     [âŠ]     constexpr initializer_list() noexcept;     initializer_list(const initializer_list&) = default;     initializer_list(initializer_list&&) = default;     initializer_list& operator=(const initializer_list&) = delete;     initializer_list& operator=(initializer_list&&) = delete;     constexpr size_t size() const noexcept;     [âŠ]   };   [âŠ] } LWG telecon appears to want a language change to disallow assigning a braced-init-list to an std::initializer_list but still permit move assignment of std::initializer_list objects. That is, auto il1 = {1,2,3}; auto il2 = {4,5,6}; il1 = {7,8,9}; // currently well-formed but dangles immediately; should be ill-formed il1 = std::move(il2); // currently well-formed and should remain so Meeting: Proposed resolution:
SF F N A SA 0 3 12 0 0 JF emailed LEWG, to see if they have an opinion, no feedback. Asked LEWG chairs to schedule for a telecon. LWG discussed priority. |
â»ïž | |
Lib |
std::function should not return dangling references |
If a std::function has a reference as a return type, and that reference binds to a prvalue returned by the callable that it wraps, then the reference is always dangling. Because any use of such a reference results in undefined behaviour, the std::function should not be allowed to be initialized with such a callable. Instead, the program should be ill-formed. A minimal example of well-formed code under the current standard that exhibits this issue: int main()Â { Â Â std::function<const int&()> F([]{ return 42; }); Â Â int x = F(); // oops! } Proposed resolution: Add a second paragraph to the remarks section of 20.14.16.2.1 [func.wrap.func.con]: template<class F> function(F f); -7- Requires: F shall be CopyConstructible. -8- Remarks: This constructor template shall not participate in overload resolution unless
[âŠ] Tim: LWG in Batavia 2018 would like a way to detect when the initialization of a reference would bind it to a temporary. This requires compiler support, since thereâs no known way in the current language to do so reliably in the presence of user-defined conversions (see thread starting at https://lists.isocpp.org/lib/2017/07/3256.php). Meeting: Tim wrote p2255 to address this. Ville thinks there should be an analysis of alternative approaches. Also see P0932. |
â»ïž | |
Core |
Restrictions on local classes |
Now that the restriction against local classes being used as template arguments has been lifted, they are more useful, yet they are still crippled. For some reason or oversight, the restriction against local classes being templates or having member templates was not lifted. Allowing local classes to have member templates facilitates generic programming (the reason for lifting the other restriction), especially when it comes to the visitor-pattern (see the boost::variant documentation and the following example) as implemented in boost and the boost::MPL library (since functors have to be template classes in mpl, and higher-order functors have to have member templates to be useful). A local class with a member template would allow this desirable solution: Â Â Â Â #include <boost/variant.hpp> Â Â Â Â int main() { Â Â Â Â Â Â struct times_two_generic: public boost::static_visitor<> { Â Â Â Â Â Â Â Â template <typename T> void operator()(T& operand) const { Â Â Â Â Â Â Â Â Â Â Â Â operand += operand; Â Â Â Â Â Â Â Â } Â Â Â Â Â Â }; Â Â Â Â Â Â std::vector<boost::variant<int, std::string>> vec; Â Â Â Â Â Â vec.push_back(21); Â Â Â Â Â Â vec.push_back("hello "); Â Â Â Â Â Â times_two_generic visitor; Â Â Â Â Â Â std::for_each(vec.begin(), vec.end(), boost::apply_visitor(visitor)); Â Â Â Â } Is there any compelling reason not to allow this code? Is there any compelling reason not to allow local classes to be templates, have friends, or be able to define their static data members at function scope? Wouldnât this symmetry amongst local and non-local classes make the language more appealing and less embarrassing? Also see p2044, seen by EWGI in Prague and requested to be merged with P1988, and implementors queried. The current paper draft addresses all of this. Meeting: (notes) Some folks unsure that we should do anything here. Revisit the resolution with P2044. Extension issues are a closed status on the issues list, like NAD Future was for LWG I find it helpful to have a status that says EWG may still be considering it. Suggest closing as Not A Defect because we have significant implementation concerns, but weâll explore the design space in P2044. All in favor. |
NAD | |
Core |
Base-derived conversion in member type of pointer-to-member conversion |
Related to CWG 170, drafting by Clark seems unlikely. This is section 2.1 of Jeff Snyderâs P0149R0, which was approved by EWG, 4 years ago, waiting for wording. JF reached out to Jeff. Did wording with Jens, main blocker is lack of implementation. Meeting: (notes) Suggest closing as Not A Defect because we have implementation uncertainties, but weâll explore the design space in P0149. ABI group will discuss. All in favor. |
NAD | |
Core |
Lifetime of temporaries in range-based for |
// some function   std::vector<int> foo();   // correct usage   auto v = foo();   for( auto i : reverse(v) ) { std::cout << i << std::endl; }   // problematic usage   for( auto i : reverse(foo()) ) { std::cout << i << std::endl; } Meeting: (notes, also discussed in Rapperswil 2014) Suggest closing as Not A Defect because itâs a change which might have effects on existing code (might cause bugs), and might need to change more than just range-based loops. See p0614, p0577, p0936, p1179. Weâll explore the design space in a separate paper, Herb circled back with Nico on this, might write a paper. All in favor. |
NAD | |
Core |
reinterpret_cast for all types with the same size and alignment |
During the discussion of issue 799, which specified the result of using reinterpret_cast to convert an operand to its own type, it was observed that it is probably reasonable to allow reinterpret_cast between any two types that have the same size and alignment. Additional note, April, 2015: It has been suggested that this question may more properly be the province of EWG, especially in light of discussions during the resolution of issue 330. The priority has been deleted to allow CWG to reconsider its status. Rationale (May, 2015): CWG agreed that this question should be considered from a language design perspective and is thus being referred to EWG. Suggest rejection: we chose to add std::bit_cast to provide exactly this functionality instead of extending reinterpret_cast. Meeting: (notes) Suggest closing as Not A Defect. bit_cast addresses some of the usecases this issue might cover. Weâd want separate papers to support other usescases, but have nothing outstanding at the moment. All in favor. |
NAD | |
Core |
Querying the alignment of an object |
Quick example using âautoâ illustrates why we might want this capability for objects as well as types. Principle of least astonishment suggests it is surprising for sizeof and alignof to behave differently in this regard. Recommend shipping this straight to core as soon as we can find a wording champion. We need to discuss with WG14. Questions for EWG to answer before forwarding:
This needs a design paper rather than going straight to core. https://godbolt.org/z/TeVA9T GCC seems to report the alignment of the object not just of decltype(object). Meeting: (notes, also discussed in Rapperswil 2014) Suggest closing as Not A Defect, the design is complex especially around alignment of object versus type. Invite a paper, Inbal will pitch in, Alidair can collaborate. All in favor. Inbalâs paper: P2152R0 |
NAD | |
Core |
Explicit specializations in non-containing namespaces |
The current wording of 9.8.1.2 [namespace.memdef] and 13.9.3 [temp.expl.spec] requires that an explicit specialization be declared either in the same namespace as the template or in an enclosing namespace. It would be convenient to relax that requirement and allow the specialization to be declared in a non-enclosing namespace to which one or more if the template arguments belongs. Additional note, April, 2015: See EWG issue 48. Might allow us to revert DR2061 and all the horribleness that created and described in p1701. The problem 1077 addresses is the motivating factor in dr2061. Also see CWG 2370. Meeting: (notes) Suggest closing as Not A Defect. See p0665, minutes. Continue under p0665 or a forked version of it. All in favor. |
NAD | |
Core |
trailing-return-type and point of declaration |
template <class T> T list(T x);     template <class H, class ...T>     auto list(H h, T ...args) -> decltype(list(args...)); // list isnât in scope in its own trailing-return-type     auto list3 = list(1, 2, 3); Meeting: (notes, also discussed in Rapperswil 2014) there might be compiler divergence according to Daveed. Suggest closing as Not A Defect, it would be tricky to change behavior without ambiguity. "Fixing" this would break existing code that relies on seeing only previous declarations. No objection to unanimous consent. |
NAD | |
Core |
Objects with no linkage in non-type template arguments |
According to 13.4.2 [temp.arg.nontype] paragraph 1 bullet 3, only objects with linkage can be used to form non-type template arguments. Is this restriction still needed? It would be convenient to use block-scope objects as template arguments. Resolved by N4268. The following is valid: template <int *> struct A; auto f() { Â Â static int x; Â Â A<&x> *ap = nullptr; Â Â return ap; } There is no longer any linkage restriction. There is a restriction on storage duration, which seems reasonable (you can use the address of a local static variable but not of a local automatic variable as a non-type template argument). Meeting: (notes, also discussed in Rapperswil 2014) Suggest closing as Not A Defect. Addressed by N4268. No objection to unanimous consent. |
NAD | |
Core |
Omitted bound in array new-expression |
The syntax for noptr-new-declarator in 7.6.2.7 [expr.new] paragraph 1 requires an expression, even though the bound could be inferred from a braced-init-list initializer. It is not clear whether 9.4.1 [dcl.init.aggr] paragraph 4, An array of unknown size initialized with a brace-enclosed initializer-list containing n initializer-clauses, where n shall be greater than zero, is defined as having n elements (9.3.3.4 [dcl.array]). should be considered to apply to the new-type-id variant, e.g., Â Â new (int[]){1, 2, 3} This was addressed by p1009 Meeting: (notes) Suggest closing as Not A Defect. Addressed by P1009. No objection to unanimous consent. |
NAD | |
Core |
Language linkage and function type compatibility |
Currently function types with different language linkage are not compatible, and 7.6.1.2 [expr.call] paragraph 1 makes it undefined behavior to call a function via a type with a different language linkage. These features are generally not enforced by most current implementations (although some do) between functions with C and C++ language linkage. Should these restrictions be relaxed, perhaps as conditionally-supported behavior? Somewhat related to CWG1463. Meeting: (notes) no strong consensus at the moment, Erich Keane brought this up with SG12 Undefined Behavior. Long discussion, will need to revisit, need a paper. Meeting Oct 22nd 2020: will need a volunteer to write a paper, but the wording in the standard is unambiguous, and we have existence proof of platforms which use different calling conventions between C and C++. However many major compilers have chosen to ignore this. Not a defect, but we welcome a paper to change the status quo. No objection to unanimous consent. |
NAD | |
Core |
Default arguments for template parameter packs |
Although 13.2 [temp.param] paragraph 9 forbids default arguments for template parameter packs, allowing them would make some program patterns easier to write. Should this restriction be removed? Meeting: (notes) Suggest closing as Not A Defect. Interesting design space, but needs a paper, see N3416. No objection to unanimous consent. |
NAD | |
Core |
List-initialization of array objects |
The resolution of issue 1467 now allows for initialization of aggregate classes from an object of the same type. Similar treatment should be afforded to array aggregates. See recent discussion on allowing 'auto x[] = {1, 2, 3};' -- this topic came up there. The two questions can be answered independently, but some consider them to be related. Meeting: (notes) Suggest closing as Not A Defect. Fixing anything in this space would require a paper which considers the entire design space, Timur might be interested in this. No objection to unanimous consent. |
NAD | |
Core |
Non-identifier characters in ud-suffix |
JF forwarded to SG16 Unicode given their work on TR31. Tracked on GitHub. SG16 reviewed D1949R3, still needs wording changes. Discussed at the April 22nd SG16 telecon. SG16 Poll: Is there any objection to unanimous consent for recommending rejection of this proposal? No objection to unanimous consent. EWG Meeting: (notes 2020-04-15, notes 2020-05-07) Suggest closing as Not A Defect. No objection to unanimous consent. |
NAD | |
Core |
Preventing explicit specialization |
A desire has been expressed for a mechanism to prevent explicitly specializing a given class template, in particular std::initializer_list and perhaps some others in the standard library. It is not clear whether simply adding a prohibition to the description of the templates in the library clauses would be sufficient or whether a core language mechanism is required. Meeting: (notes) Suggest closing as Not A Defect. No objection to unanimous consent. This could be a language feature, would need library usecase examples. Poll: we are interested in such a paper SF 2 F 13 N 6 A 1 SA 0 |
NAD | |
Core |
Potentially-invoked destructors in non-throwing constructors |
Since the base class constructor is non-throwing, the deleted base class destructor need not be referenced. Thereâs a typo in the issues list here: it should say "Since the derived class constructor is non-throwing, the deleted base class destructor need not be referenced." Meeting: (notes 2020-04-23) the proposed wording changes the implementation leeway in two-phase unwinding, which breaks some existing ABIs. We would need a paper to explore this further. Suggest closing as Not A Defect. No objection to unanimous consent. |
NAD | |
Core |
Lvalues of type void |
There does not seem to be any significant technical obstacle to allowing a void* pointer to be dereferenced, and that would avoid having to use weighty circumlocutions when casting to a reference to an object designated by such a pointer. Might consider this a duplicate of the discussion on "regular void". JF reached out to Matt. He has an implementation in clang. Needs to update the paper. Might need a volunteer to present. Daveed would be interested in presenting. Meeting: (notes 2020-04-23) Suggest closing as Not A Defect. Explore under the âregular voidâ umbrella. No objection to unanimous consent. |
NAD | |
Core |
Relaxing exception-specification compatibility requirements |
According to 14.5 [except.spec] paragraph 4, If any declaration of a function has an exception-specification that is not a noexcept-specification allowing all exceptions, all declarations, including the definition and any explicit specialization, of that function shall have a compatible exception-specification. This seems excessive for explicit specializations, considering that paragraph 6 applies a looser requirement for virtual functions: If a virtual function has an exception-specification, all declarations, including the definition, of any function that overrides that virtual function in any derived class shall only allow exceptions that are allowed by the exception-specification of the base class virtual function. The rule in paragraph 3 is also problematic in regard to explicit specializations of destructors and defaulted special member functions, as the implicit exception-specification of the template member function cannot be determined. There is also a related problem with defaulted special member functions and exception-specifications. According to 9.5.2 [dcl.fct.def.default] paragraph 3, If a function that is explicitly defaulted has an explicit exception-specification that is not compatible (14.5 [except.spec]) with the exception-specification on the implicit declaration, then
This rule precludes defaulting a virtual base class destructor or copy/move functions if the derived class function will throw an exception not allowed by the implicit base class member function. Meeting: (notes 2020-04-23) JF will work with Mike to update wording to C++20. Will revisit. From Mike: This issue is NAD since we eliminated typed exception-specifications. The current wording, dealing only with noexcept(true) and noexcept(false), does not have this issue. Will remove âextensionâ status. Meeting: no objection to CWG taking it back, and marking it as NAD. |
NAD | |
Core |
decltype(auto) with direct-list-initialization |
Paper N3922 changed the rules for deduction from a braced-init-list containing a single expression in a direct-initialization context. Should a corresponding change be made for decltype(auto)? E.g.,   auto x8a = { 1 };      // decltype(x8a) is std::initializer_list<int>   decltype(auto) x8d = { 1 }; // ill-formed, a braced-init-list is not an expression   auto x9a{ 1 };       // decltype(x9a) is int   decltype(auto) x9d{ 1 };  // decltype(x9d) is int See also issue 1467, which also effectively ignores braces around a single expression, this change would be parallel to that one, even though the primary motivation for delctype(auto) is in the return type of a forwarding function, where direct-initialization does not apply. Meeting: (notes 2020-04-23) Suggest closing as Not A Defect. This would be a language change, itâs unclear that we want to make such a change. It would require a paper. Mike Spertus is writing a paper with some overlap, will cover this as well. No objection to unanimous consent. |
NAD | |
Core |
Array temporaries in reference binding |
The current wording of the Standard appears to permit code like
creating a temporary array of ten elements and binding the parameter reference to it. This is controversial and should be reconsidered. (See issues 1058 and 1232.) Meeting: (notes 2020-04-23) JF digging more, talking to Richard about this. Somewhat related to P2174 compound literals. Would be very strange if  ... were invalid but ...   ... were both OK. Maybe either we should allow the trailing elements to be zeroed in general (the status quo), or not (a major breaking change). Which means we should reject the issue on consistency grounds. The general rule is that if  T &&r = init; ... canât bind directly, we create a temporary initialized as if with  T r = init; ... and bind to that. (And similarly for const references.) Another question: Do we want to support (T){inits} as a synonym for T{inits}? Meeting Oct 22nd 2020: Note that the issue itself is defective, and CWG2352 references p1358, and was resolved, leading us to believe that this is now mainstream and not controversial. Not a defect. No objection to unanimous consent. |
NAD | |
Core |
Copy elision and comma operator |
Currently, _N4750_.15.8 [class.copy] paragraphs 31-32 apply only to the name of a local variable in determining whether a return expression is a candidate for copy elision or move construction. Would it make sense to extend that to include the right operand of a comma operator? X f() { Â Â X x; Â Â return (0, x); } Meeting: (notes 2020-04-23) Consider expanding to other places that expand bit-field-ness such as return b ? throw : x;. Suggest closing as Not A Defect. Will need a paper to address, no current volunteer for this. No objection to unanimous consent. |
NAD | |
Core |
Deprecated default generated copy constructors |
EWG has indicated that they are not currently in favor of removing the implicitly declared defaulted copy constructors and assignment operators that are eprecated in _N4750_.15.8 [class.copy] paragraphs 7 and 18. Should this deprecation be removed? Related: discussing under p2139 deprecations. Meeting: (note 2020-04-29) Suggest closing as Not A Defect. No objection to unanimous consent. We either want to remove entirely, or un-deprecate. This will need a paper, Ville will talk with Alisdair about forking the topic from p2139. |
NAD | |
Core |
Value-initialization of array types |
Although value-initialization is defined for array types and the () initializer is permitted in a mem-initializer naming an array member of a class, the syntax T() (where is an array type) is explicitly forbidden by 7.6.1.3 [expr.type.conv] paragraph 2. This is inconsistent and the syntax should be permitted. Rationale (July, 2009): The CWG was not convinced of the utility of this extension, especially in light of questions about handling the lifetime of temporary arrays. This suggestion needs a proposal and analysis by the EWG before it can be considered by the CWG. This has become a more severe inconsistency after we adopted Villeâs P0960 for C++20. Now itâs not only () that has this weird special-case restriction, itâs (a, b, c) too: using X = int[]; X x{1, 2, 3}; // ok, int[3] X y(1, 2, 3); // ok, int[3] f(X{1, 2, 3}); // ok, int[3] temporary f(X(1, 2, 3)); // error Meeting: (notes) it is a defect, need a paper. David Stone trying to find a volunteer to write said paper. All in favor. |
Paper needed | |
Core |
extern "C" alias templates |
Currently 13 [temp] paragraph 4 forbids any template from having C linkage. Should alias templates be exempt from this prohibition, since they do not have any linkage? Additional note, April, 2013: It was suggested (see messages 23364 through 23367) that relaxing this restriction for alias templates could provide a way of addressing the long-standing lack of a way of specifying a language linkage for a dependent function type (see issue 13). The priority was deleted to allow CWG to consider the implications of that potential application of the facility. We should either have some way to express a dependent function type with C language linkage (and should accept 1555 below) or we should remove the notion that C language linkage (or not) is part of the function type at all. (Apparently some targets used it; are they still in use? EDG probably knows.) Actively discussed on CWG reflector. Davisâ interpretation of CWG discussion: I donât speak for Core, of course, but my (Evolutionary) thoughts are those given (last) in the message to which you replied: neither the wording nor the apparent intent of [temp.pre]/6âs restrictions on C linkage for templates make any sense. Since templates (and explicit specializations) canât have C linkage of the name-mangling variety (which the standard calls language linkage of a (function) name) but can have C linkage of the calling-convention variety (which the standard calls language linkage of a (function) type), extern "C" should grant them the latter and not the former with no error. This has certain obvious applications involving C APIs with callbacks. (Put differently, CWG13 shouldnât have been rejected; it appears to have gotten bogged down in questions of syntax, but we have an adequate syntactic workaround that we merely have to permit.) CWG1463 asks for a (very) proper subset of the above: merely that extern "C" be allowed to apply to alias templates (claiming incorrectly that they have no name with linkage at all). I consider it more relevant (and more productive) to talk about whether entities have names with language linkage than with the ordinary kind. The Core reflector discussion (which seems to have finished for the moment) also touched on the case where "the same" function template is declared with two different language linkages for its type, but the only relevant Evolution input there would be a decision to go the opposite way and forbid function templates from having types with C language linkage entirely. (They currently can, but itâs mostly or entirely useless.) If (for CWG1555, also on your list) the rules about language linkage of (function) types are sufficiently relaxed, then CWG1463 may be moot (and my extension of it with it), but that seems unlikely given Hubertâs recent identification of a case where they matter. Meeting: (notes 2020-04-15, notes 2020-10-22, also discussed in Rapperswil 2014) We agree that this is an issue. extern âCâ on a template should only affect calling convention, and not the mangling. Davis and Hubert volunteer to write a paper. Unanimous consent. |
Paper needed | |
Core |
Ellipsis following function parameter pack |
Although the current wording permits an ellipsis to immediately follow a function parameter pack, it is not clear that the <cstdarg> facilities permit access to the ellipsis arguments. The problem here (which is not explained in the issue) is: how do you supply the name of the last parameter before the ellipsis to va_start? You canât put the name of a pack there (it wouldnât be expanded) and thereâs no way to name the last element of the pack (nor to deal with the case where the pack is empty). Meeting: (notes) 3 options: fix wording around âlast parameterâ, remove facility entirely (either va_start or function declarator), try to invent a language facility. JF emailed EWG to see if anyone has a strong preference, or if we should send back to CWG to fix wording, long discussion. Michael Spertus: I am willing to commit to including and analysis on this in an upcoming paper on parameter packs. JF followed up with Michael and Barry, no response. |
Paper needed | |
Core |
Type of __func__ |
Two questions have arisen regarding the treatment of the type of the __func__ built-in variable. First, some implementations accept   void f() {     typedef decltype(__func__) T;     T x = __func__;   } even though T is specified to be an array type. In a related question, it was noted that __func__ is implicitly required to be unique in each function, and that not only the value but the type of __func__ are implementation-defined; e.g., in something like   inline auto f() { return &__func__; } the function type is implementation-specific. These concerns could be addressed by making the value a prvalue of type const char* instead of an array lvalue. Rationale (November, 2018): See also issue 2362, which asks for the ability to use __func__ in a constexpr function. These two goals are incompatible. The deep question here is about __func__ and the ODR. Does EWG want implementations to somehow behave as if __func__ is the same in all copies of an inline function (in which case it can have an array type and be usable in constant expressions, but the demangling algorithm used to construct it becomes part of the ABI), or does EWG want implementations to behave as if __func__ may differ between copies, so is in effect not known until runtime (in which case it must have either pointer or incomplete array type, and its value is not usable in constant expressions -- but its address could still be usable). Note: C++20 has std::source_location::function_name. Meeting: (notes 2020-04-23) We should discuss this with WG14. This is indeed a language issue. No objection to unanimous consent. Weâll need a paper, potentially considering what Reflection could do, JF brought it up on the mailing list. We probably need a paper to disentangle this. |
Paper needed | |
Core |
Ambiguity resolution for cast to function type |
C++ has a blanket disambiguation rule that says if a sequence of tokens can be interpreted as either a type-name or an expression, the type-name interpretation is chosen. This is unhelpful in cases like     (T())+3 where the current rules make "(T())" a cast to the type "function with no parameters returning T" rather than a parenthesized value-initialization of a temporary of type T. The former interpretation is always ill-formed - you canât cast to a function type - while the latter could be useful. Richardâs proposed resolution, cited above, is to avoid the ambiguity by changing the grammar so that cases like "(T())" cannot be parsed as a cast. The wording in the proposal applies that change to a number of different contexts where the ambiguity can come into play. There are two contexts where the change is _not_ applied, however: 1) the operand of typeid, and 2) a template-argument. During our discussion yesterday, there was some support for the idea of applying the change to typeid, as well, although that would be a breaking change for any programs that rely on the current disambiguation to get type information for such function types. There was general agreement, however, to exclude template arguments, since they are used for things like std::function. CWG would, therefore, like some guidance from EWG on two questions. First, should we apply the new syntax to the operand of typeid, even though itâs a breaking change? More generally, the question was raised whether we should make this change at all. Although resolving the ambiguity in the other direction would arguably be more convenient in many cases, there is a tension between that convenience and the complexity of the language. In particular, we would be creating a situation where the exact same sequence of tokens would mean two different things, depending on the context in which they appear. Is the convenience worth the cost in complexity? Meeting: (note 2020-04-29, notes 2020-03-23, note from Core summer 2020, notes from Core Prague 2020, notes from Core 2019-01-07, notes from Core Kona 2019, notes from Core Cologne 2019) This is an issue, weâd like to change the standard to resolve it: SF 0 F 6 N 4 A 3 SA 2 Davis emailed EWG reflector. Long discussion. |
Paper needed | |
Core |
Are default argument instantiation failures in the âimmediate contextâ? |
Example 1: template <typename T, typename U = T> void fun(T v, U u = U()) {} void fun(...) {} struct X { Â Â Â Â X(int) {} // no default ctor }; int main()Â {Â fun (X(1)); } Consider the following example (taken from issue 3 of paper P0348R0): Example 2: Â Â template <typename U> void fun(U u = U()); Â Â struct X { Â Â Â Â X(int) {} Â Â }; Â Â template <class T> decltype(fun<T>()) g(int) { } Â Â template <class> void g(long) { } Â Â int main() { g<X>(0); } When is the substitution into the return type done? The current specification makes this example ill-formed because the failure to instantiate the default argument in the decltype operand is not in the immediate context of the substitution, although a plausible argument for making this a SFINAE case can be made. Meeting:Â (notes 2020-05-07) The first example under issue 3 of paper P0348R0 should become well-formed. SF F N A SA 0 1 4 3 6 The second example under issue 3 of paper P0348R0 should become well-formed. SF F N A SA 1 5 7 3 0 This is an issue. Weâd like to see a paper addressing it. It should explore what âImmediate contextâ means. No objection to unanimous consent. Daveed / Hubert might entertain writing a paper explaining this. Ville emailed EWG about this. JF contacted Andrzej to see if heâs interested in addressing this. Not sure he is. Meeting 2020-10-28: Tomasz will write a paper which exposes the issue and what he thinks should be done (but not resolving wording itself). Hubert remembers an email about this, will find it and sync with JF. Meeting 2021-01-14: Andrzej wrote a paper for this (emailed 2021-01-12 to EWG). |
Paper needed | |
Core |
__func__ should be constexpr |
The definition of __func__ in 9.5.1 [dcl.fct.def.general] paragraph 8 is:   static const char __func__[] = "function-name"; This prohibits its use in constant expressions, e.g.,   int main () {     // error: the value of __func__ is not usable in a constant expression     constexpr char c = __func__[0];   } Rationale (November, 2018): See also issue 1962, which asks that the type of __func__ be const char*. These two goals are incompatible. Meeting: handle with 1962. |
Paper needed |
9. Near-future EWG plans
We will continue to work on issue resolution and C++23, prioritizing according to [P0592R4].