From Jason Turner

[dcl.contract.func]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmplkt9qqzd/{from.md → to.md} +171 -0
tmp/tmplkt9qqzd/{from.md → to.md} RENAMED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### General <a id="dcl.contract.func">[[dcl.contract.func]]</a>
2
+
3
+ ``` bnf
4
+ function-contract-specifier-seq:
5
+ function-contract-specifier function-contract-specifier-seqₒₚₜ
6
+ ```
7
+
8
+ ``` bnf
9
+ function-contract-specifier:
10
+ precondition-specifier
11
+ postcondition-specifier
12
+ ```
13
+
14
+ ``` bnf
15
+ precondition-specifier:
16
+ 'pre' attribute-specifier-seqₒₚₜ '(' conditional-expression ')'
17
+ ```
18
+
19
+ ``` bnf
20
+ postcondition-specifier:
21
+ 'post' attribute-specifier-seqₒₚₜ '(' result-name-introducerₒₚₜ conditional-expression ')'
22
+ ```
23
+
24
+ A *function contract assertion* is a contract assertion
25
+ [[basic.contract.general]] associated with a function. A
26
+ *precondition-specifier* introduces a *precondition assertion*, which is
27
+ a function contract assertion associated with entering a function. A
28
+ *postcondition-specifier* introduces a *postcondition assertion*, which
29
+ is a function contract assertion associated with exiting a function
30
+ normally.
31
+
32
+ [*Note 1*: A postcondition assertion is not associated with exiting a
33
+ function in any other fashion, such as via an exception [[expr.throw]]
34
+ or via a call to `longjmp` [[csetjmp.syn]]. — *end note*]
35
+
36
+ The predicate [[basic.contract.general]] of a function contract
37
+ assertion is its *conditional-expression* contextually converted to
38
+ `bool`.
39
+
40
+ Each *function-contract-specifier* of a
41
+ *function-contract-specifier-seq* (if any) of an unspecified first
42
+ declaration [[basic.def]] of a function introduces a corresponding
43
+ function contract assertion for that function. The optional
44
+ *attribute-specifier-seq* following `pre` or `post` appertains to the
45
+ introduced contract assertion.
46
+
47
+ [*Note 2*: The *function-contract-specifier-seq* of a
48
+ *lambda-declarator* applies to the function call operator or operator
49
+ template of the corresponding closure type
50
+ [[expr.prim.lambda.closure]]. — *end note*]
51
+
52
+ A declaration D of a function or function template *f* that is not a
53
+ first declaration shall have either no *function-contract-specifier-seq*
54
+ or the same *function-contract-specifier-seq* (see below) as any first
55
+ declaration F reachable from D. If D and F are in different translation
56
+ units, a diagnostic is required only if D is attached to a named module.
57
+ If a declaration F₁ is a first declaration of `f` in one translation
58
+ unit and a declaration F₂ is a first declaration of `f` in another
59
+ translation unit, F₁ and F₂ shall specify the same
60
+ *function-contract-specifier-seq*, no diagnostic required.
61
+
62
+ A *function-contract-specifier-seq* S₁ is the same as a
63
+ *function-contract-specifier-seq* S₂ if S₁ and S₂ consist of the same
64
+ *function-contract-specifier*s in the same order. A
65
+ *function-contract-specifier* C₁ on a function declaration D₁ is the
66
+ same as a *function-contract-specifier* C₂ on a function declaration D₂
67
+ if
68
+
69
+ - their predicates P₁ and P₂ would satisfy the one-definition rule
70
+ [[basic.def.odr]] if placed in function definitions on the
71
+ declarations D₁ and D₂, respectively, except for
72
+ - renaming of the parameters of *f*,
73
+ - renaming of template parameters of a template enclosing **, and
74
+ - renaming of the result binding [[dcl.contract.res]], if any,
75
+
76
+ and, if D₁ and D₂ are in different translation units, corresponding
77
+ entities defined within each predicate behave as if there is a single
78
+ entity with a single definition, and
79
+ - both C₁ and C₂ specify a *result-name-introducer* or neither do.
80
+
81
+ If this condition is not met solely due to the comparison of two
82
+ *lambda-expression*s that are contained within P₁ and P₂, no diagnostic
83
+ is required.
84
+
85
+ [*Note 3*: Equivalent *function-contract-specifier-seq*s apply to all
86
+ uses and definitions of a function across all translation
87
+ units. — *end note*]
88
+
89
+ [*Example 1*:
90
+
91
+ ``` cpp
92
+ bool b1, b2;
93
+
94
+ void f() pre (b1) pre ([]{ return b2; }());
95
+ void f(); // OK, function-contract-specifiers omitted
96
+ void f() pre (b1) pre ([]{ return b2; }()); // error: closures have different types.
97
+ void f() pre (b1); // error: function-contract-specifiers only partially repeated
98
+
99
+ int g() post(r : b1);
100
+ int g() post(b1); // error: mismatched result-name-introducer presence
101
+
102
+ namespace N {
103
+ void h() pre (b1);
104
+ bool b1;
105
+ void h() pre (b1); // error: function-contract-specifiers differ according to
106
+ // the one-definition rule[basic.def.odr].
107
+ }
108
+ ```
109
+
110
+ — *end example*]
111
+
112
+ A virtual function [[class.virtual]], a deleted function
113
+ [[dcl.fct.def.delete]], or a function defaulted on its first declaration
114
+ [[dcl.fct.def.default]] shall not have a
115
+ *function-contract-specifier-seq*.
116
+
117
+ If the predicate of a postcondition assertion of a function *f* odr-uses
118
+ [[basic.def.odr]] a non-reference parameter of *f*, that parameter and
119
+ the corresponding parameter on all declarations of *f* shall have
120
+ `const` type.
121
+
122
+ [*Note 4*:
123
+
124
+ This requirement applies even to declarations that do not specify the
125
+ *postcondition-specifier*. Parameters with array or function type will
126
+ decay to non-`const` types even if a `const` qualifier is present.
127
+
128
+ [*Example 2*:
129
+
130
+ ``` cpp
131
+ int f(const int i[10])
132
+ post(r : r == i[0]); // error: i has type const int * (not int* const).
133
+ ```
134
+
135
+ — *end example*]
136
+
137
+ — *end note*]
138
+
139
+ [*Note 5*: The function contract assertions of a function are evaluated
140
+ even when invoked indirectly, such as through a pointer to function or a
141
+ pointer to member function. A pointer to function, pointer to member
142
+ function, or function type alias cannot have a
143
+ *function-contract-specifier-seq* associated directly with
144
+ it. — *end note*]
145
+
146
+ The function contract assertions of a function are considered to be
147
+ *needed* [[temp.inst]] when
148
+
149
+ - the function is odr-used [[basic.def.odr]] or
150
+ - the function is defined.
151
+
152
+ [*Note 6*:
153
+
154
+ Overload resolution does not consider *function-contract-specifier*s
155
+ [[temp.deduct]], [[temp.inst]].
156
+
157
+ [*Example 3*:
158
+
159
+ ``` cpp
160
+ template <typename T> void f(T t) pre( t == "" );
161
+ template <typename T> void f(T&& t);
162
+ void g()
163
+ {
164
+ f(5); // error: ambiguous
165
+ }
166
+ ```
167
+
168
+ — *end example*]
169
+
170
+ — *end note*]
171
+