Created on 2019-03-04.00:00:00 last changed 54 months ago
Proposed resolution:
This wording is relative to N4861.
Change [structure.specifications], as indicated:
-3- Descriptions of function semantics contain the following elements (as appropriate); some of these elements may also appear in the description of non-function entities as denoted below: (footnote […])
(3.1) — Constraints: […]
(3.2) — Mandates: the conditions that, if not met, render the program ill-formed. [Example: An implementation might express such a condition via the constant-expression in a static_assert-declaration ([dcl.pre]). If the diagnostic is to be emitted only after the function has been selected by overload resolution, an implementation might express such a condition via a constraint-expression ([temp.constr.decl]) and also define the function as deleted. — end example]
(3.3) — Preconditions: the conditions imposed on a non-function entity, or that the function assumes to hold whenever it is called.
[…]
(3.10) — Remarks: additional semantic constraints
on the function.[…]
Change [res.on.expects], as indicated:
-1- Violation of any preconditions specified in a
function'sPreconditions: element results in undefined behavior.
Change [depr.res.on.required], as indicated:
[Drafting note: Interestingly, albey the Requires: element has nearly vanished, the issue is still relevant, see [depr.meta.types]]
-1- Violation of any preconditions specified in a
function'sRequires: element results in undefined behavior unless the function's Throws: element specifies throwing an exception whenthea function's precondition is violated.
[ 2020-06-11; Jonathan comments ]
This issue also affects some type traits such as alignment_of and make_signed/make_unsigned. In addition to clarifying what Mandates: means on a non-function we need to decide exactly what is being mandated in the type traits. Is instantiating the class template ill-formed, or just odr-using the nested type or value member?
[ 2020-05-01; Daniel comments and adjusts wording to recent working draft ]
It should be pointed out that the originally referred to Expects: element has since then be renamed to Preconditions: and that the Requires: element does now only occur in annex D.
[ 2019-03-15; Daniel comments and provides wording ]
During the preparation of the wording for this issue it was found that we should allow Remarks: elements to be used for other things than functions. One example of imposed restrictions can be found in [cmp.common]:
template<class... Ts> struct common_comparison_category { using type = see below; };-2- Remarks: The member typedef-name type denotes the common comparison type ([class.spaceship]) of Ts..., the expanded parameter pack. […]
The discussion of this issue speaks of "type" restrictions (versus the specified restrictions on functions), because even the non-type template argument restrictions of [pair.astuple] appear in the context of a member type specification, but there are examples where not really a single (member) type is involved, e.g. in the [tuple.helper] example mentioned above.
Another example is when such elements are used for the specification of template specializations, e.g. in [tuple.helper]:template<class T> struct tuple_size;-1- Remarks: All specializations of tuple_size shall satisfy the Cpp17UnaryTypeTrait requirements ([meta.rqmts]) with a base characteristic of integral_constant<size_t, N> for some N.
Besides class template specializations, a second relevant use-case is the specification of member types (Which are not necessarily part of a template), typically within the requirement tables, e.g. in Table 62 — "Container requirements"'s entry X::value_type:
Requires: T is Cpp17Erasable from X
The suggested wording tries to cover the generalization by means of the term "non-function entities" in addition to the existing functions to prevent being enforced to enumerate all entities to which the extended rules apply.
Previous resolution [SUPERSEDED]:This wording is relative to N4810.
Change [structure.specifications], as indicated:
-3- Descriptions of function semantics contain the following elements (as appropriate); some of these elements may also appear in the description of non-function entities as denoted below: (footnote […])
(3.1) — Requires: the preconditions imposed on a non-function entity, or for calling the function.
(3.2) — Constraints: […]
(3.3) — Mandates: the conditions that, if not met, render the program ill-formed. [Example: An implementation might express such a condition via the constant-expression in a static_assert-declaration (Clause 9). If the diagnostic is to be emitted only after the function has been selected by overload resolution, an implementation might express such a condition via a constraint-expression ([temp.constr.decl]) and also define the function as deleted. — end example]
(3.4) — Expects: the conditions (sometimes termed preconditions) imposed on a non-function entity, or that the function assumes to hold whenever it is called. [Example: An implementation might express such conditions via an attribute such as [[expects]] ([dcl.attr.contract]) on a function declaration. However, some such conditions might not lend themselves to expression via code. — end example]
[…]
(3.11) — Remarks: additional semantic constraints
on the function.[…]
Change [res.on.required], as indicated:
-1- Violation of any preconditions specified in a
-2- Violation of any preconditions specified in anfunction'sRequires: element results in undefined behavior unless the function's Throws: element specifies throwing an exception whenthea function's precondition is violated.function'sExpects: element results in undefined behavior.
[ 2019-03-15 Priority set to 3 after reflector discussion ]
The working paper uses the special elements Mandates:, Expects: as well as Requires: to types, albeit [structure.specifications] defines them only for functions, for example [structure.specifications] sub-bullet (3.4):
Expects: the conditions (sometimes termed preconditions) that the function assumes to hold whenever it is called.
Examples for such usages on types are (from N4800):
[char.traits.typedefs] for types int_type and state_type
[pair.astuple] for tuple_element<I, pair<T1, T2>>::type
[tuple.helper] for tuple_element<I, tuple<Types...>>::type
[tuple.traits] for uses_allocator<tuple<Types...>, Alloc>
Table 62 — "Container requirements" for type XX::value_type
Table 65 — "Allocator-aware container requirements" for type allocator_type
Table 69 — "Associative container requirements" for types X::value_type and X::key_compare
Table 70 — "Unordered associative container requirements" for types X::value_type and X::key_equal
Instead of replacing these elements usages for these places by extra wording to reach the same effects I recommend to update instead [structure.specifications] to ensure that requirement-expressing elements are defined in a way that it also allows to express requirements imposed on types by these elements to standardize "existing practice".
Considering details, it seems obvious that Mandates:, Expects: as well as Requires: are "suitable" to be defined for types (With the acceptance of P1463R1 there are now also Mandates: for types such as Table 65 — "Allocator-aware container requirements" for type allocator_type). For Constraints: the meaning would not be so clear: Should it mean that there is conditionally a type defined or not? According to the submitters knowledge there are currently no known examples for Constraints: to specify constraint on types, therefore I'm suggesting to restrict this extension to Mandates:, Expects:, and Requires: alone.History | |||
---|---|---|---|
Date | User | Action | Args |
2020-06-11 16:19:53 | admin | set | messages: + msg11329 |
2020-05-01 19:07:51 | admin | set | messages: + msg11249 |
2019-03-15 22:22:11 | admin | set | messages: + msg10351 |
2019-03-15 20:28:59 | admin | set | messages: + msg10349 |
2019-03-15 20:28:59 | admin | set | messages: + msg10348 |
2019-03-04 00:00:00 | admin | create |