|
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