|
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-specifier-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.
|
|
4289 | 4296 | \begin{codeblock}
|
4290 | 4297 | class A {
|
4291 | 4298 | typedef int I; // private member
|
4292 |
| - I f(); |
4293 |
| - friend I g(I); |
| 4299 | + I f() pre(A::x > 0); |
| 4300 | + friend I g(I) post(A::x <= 0); |
4294 | 4301 | static I x;
|
4295 | 4302 | template<int> struct Q;
|
4296 | 4303 | template<int> friend struct R;
|
4297 | 4304 | protected:
|
4298 | 4305 | struct B { };
|
4299 | 4306 | };
|
4300 | 4307 |
|
4301 |
| -A::I A::f() { return 0; } |
4302 |
| -A::I g(A::I p = A::x); |
| 4308 | +A::I A::f() pre(A::x > 0) { return 0; } |
| 4309 | +A::I g(A::I p = A::x) post(A::x <= 0); |
4303 | 4310 | A::I g(A::I p) { return 0; }
|
4304 | 4311 | A::I A::x = 0;
|
4305 | 4312 | template<A::I> struct A::Q { };
|
|
5720 | 5727 | \tcode{typeid}
|
5721 | 5728 | operator\iref{expr.typeid} or of a
|
5722 | 5729 | \keyword{dynamic_cast}\iref{expr.dynamic.cast}.
|
5723 |
| -However, if these operations are performed in a |
5724 |
| -\grammarterm{ctor-initializer} |
| 5730 | +However, if these operations are performed |
| 5731 | +during evaluation of |
| 5732 | +\begin{itemize} |
| 5733 | +\item |
| 5734 | +a \grammarterm{ctor-initializer} |
5725 | 5735 | (or in a function called directly or indirectly from a
|
5726 | 5736 | \grammarterm{ctor-initializer})
|
5727 | 5737 | before all the
|
5728 | 5738 | \grammarterm{mem-initializer}{s}
|
5729 |
| -for base classes have completed, the program has undefined behavior. |
| 5739 | +for base classes have completed, |
| 5740 | +\item |
| 5741 | +a precondition assertion of a constructor, or |
| 5742 | +\item |
| 5743 | +a postcondition assertion of a destructor\iref{dcl.contract.func}, |
| 5744 | +\end{itemize} |
| 5745 | +the program has undefined behavior. |
5730 | 5746 | \begin{example}
|
5731 | 5747 | \begin{codeblock}
|
5732 | 5748 | class A {
|
|
6049 | 6065 | or from a destructor,
|
6050 | 6066 | including during the construction or destruction of the class's non-static data
|
6051 | 6067 | members,
|
| 6068 | +or during the evaluation of |
| 6069 | +a postcondition assertion of a constructor or |
| 6070 | +a precondition assertion of a destructor\iref{dcl.contract.func}, |
6052 | 6071 | and the object to which the call applies is the object (call it \tcode{x}) under construction or
|
6053 | 6072 | destruction,
|
6054 | 6073 | the function called is the
|
|
0 commit comments