|
475 | 475 |
|
476 | 476 | \begin{bnf} |
477 | 477 | \nontermdef{member-declarator}\br |
478 | | - declarator \opt{virt-specifier-seq} \opt{pure-specifier}\br |
479 | | - declarator requires-clause\br |
| 478 | + declarator \opt{virt-specifier-seq} \opt{function-contract-spceifier-seq} \opt{pure-specifier}\br |
| 479 | + declarator requires-clause \opt{function-contract-specifier-seq}\br |
480 | 480 | declarator brace-or-equal-initializer\br |
481 | 481 | \opt{identifier} \opt{attribute-specifier-seq} \terminal{:} constant-expression \opt{brace-or-equal-initializer} |
482 | 482 | \end{bnf} |
|
527 | 527 | the program is ill-formed; see~\ref{temp.spec.general}. |
528 | 528 | \end{note} |
529 | 529 |
|
| 530 | +\pnum |
| 531 | +The optional \grammarterm{function-contract-specifier-seq}\iref{dcl.contract.func}) |
| 532 | +in a \grammarterm{member-declarator} |
| 533 | +shall be present only if |
| 534 | +the \grammarterm{declarator} declares a function. |
| 535 | + |
530 | 536 | \pnum |
531 | 537 | \indextext{definition!class}% |
532 | 538 | The \grammarterm{member-specification} in a class definition declares the |
|
618 | 624 | \item function body\iref{dcl.fct.def.general}, |
619 | 625 | \item default argument\iref{dcl.fct.default}, |
620 | 626 | \item default template argument\iref{temp.param}, |
621 | | -\item \grammarterm{noexcept-specifier}\iref{except.spec}, or |
| 627 | +\item \grammarterm{noexcept-specifier}\iref{except.spec}, |
| 628 | +\item \grammarterm{function-contract-specifier}\iref{dcl.contract.func}, or |
622 | 629 | \item default member initializer |
623 | 630 | \end{itemize} |
624 | 631 | within the \grammarterm{member-specification} of the class or class template. |
|
4278 | 4285 | \begin{codeblock} |
4279 | 4286 | class A { |
4280 | 4287 | typedef int I; // private member |
4281 | | - I f(); |
4282 | | - friend I g(I); |
| 4288 | + I f() pre(A::x > 0); |
| 4289 | + friend I g(I) post(A::x <= 0); |
4283 | 4290 | static I x; |
4284 | 4291 | template<int> struct Q; |
4285 | 4292 | template<int> friend struct R; |
4286 | 4293 | protected: |
4287 | 4294 | struct B { }; |
4288 | 4295 | }; |
4289 | 4296 |
|
4290 | | -A::I A::f() { return 0; } |
4291 | | -A::I g(A::I p = A::x); |
| 4297 | +A::I A::f() pre(A::x > 0) { return 0; } |
| 4298 | +A::I g(A::I p = A::x) post(A::x <= 0); |
4292 | 4299 | A::I g(A::I p) { return 0; } |
4293 | 4300 | A::I A::x = 0; |
4294 | 4301 | template<A::I> struct A::Q { }; |
|
5709 | 5716 | \tcode{typeid} |
5710 | 5717 | operator\iref{expr.typeid} or of a |
5711 | 5718 | \keyword{dynamic_cast}\iref{expr.dynamic.cast}. |
5712 | | -However, if these operations are performed in a |
5713 | | -\grammarterm{ctor-initializer} |
| 5719 | +However, if these operations are performed |
| 5720 | +during evaluation of |
| 5721 | +\begin{itemize} |
| 5722 | +\item |
| 5723 | +a \grammarterm{ctor-initializer} |
5714 | 5724 | (or in a function called directly or indirectly from a |
5715 | 5725 | \grammarterm{ctor-initializer}) |
5716 | 5726 | before all the |
5717 | 5727 | \grammarterm{mem-initializer}{s} |
5718 | | -for base classes have completed, the program has undefined behavior. |
| 5728 | +for base classes have completed, |
| 5729 | +\item |
| 5730 | +a precondition assertion of a constructor, or |
| 5731 | +\item |
| 5732 | +a postcondition assertion of a destructor\iref{dcl.contract.func}, |
| 5733 | +\end{itemize} |
| 5734 | +the program has undefined behavior. |
5719 | 5735 | \begin{example} |
5720 | 5736 | \begin{codeblock} |
5721 | 5737 | class A { |
|
6038 | 6054 | or from a destructor, |
6039 | 6055 | including during the construction or destruction of the class's non-static data |
6040 | 6056 | members, |
| 6057 | +or during the evaluation of |
| 6058 | +a postcondition assertion of a constructor or |
| 6059 | +a precondition assertion of a destructor\iref{dcl.contract.func}, |
6041 | 6060 | and the object to which the call applies is the object (call it \tcode{x}) under construction or |
6042 | 6061 | destruction, |
6043 | 6062 | the function called is the |
|
0 commit comments