|
6760 | 6760 | \indextext{atomic!operation|)}%
|
6761 | 6761 | \indextext{threads!multiple|)}
|
6762 | 6762 |
|
| 6763 | +\rSec2[except.throw]{Throwing an exception}% |
| 6764 | +\indextext{exception handling!throwing}% |
| 6765 | +\indextext{throwing|see{exception handling, throwing}} |
| 6766 | + |
| 6767 | +\pnum |
| 6768 | +Throwing an exception transfers control to a handler. |
| 6769 | +\begin{note} |
| 6770 | +An exception can be thrown from one of the following contexts: |
| 6771 | +\grammarterm{throw-expression}{s}\iref{expr.throw}, |
| 6772 | +allocation functions\iref{basic.stc.dynamic.allocation}, |
| 6773 | +\keyword{dynamic_cast}\iref{expr.dynamic.cast}, |
| 6774 | +\keyword{typeid}\iref{expr.typeid}, |
| 6775 | +\grammarterm{new-expression}{s}\iref{expr.new}, and standard library |
| 6776 | +functions\iref{structure.specifications}. |
| 6777 | +\end{note} |
| 6778 | +An object is passed and the type of that object determines which handlers |
| 6779 | +can catch it. |
| 6780 | +\begin{example} |
| 6781 | +\begin{codeblock} |
| 6782 | +throw "Help!"; |
| 6783 | +\end{codeblock} |
| 6784 | +can be caught by a |
| 6785 | +\grammarterm{handler} |
| 6786 | +of |
| 6787 | +\keyword{const} |
| 6788 | +\tcode{\keyword{char}*} |
| 6789 | +type: |
| 6790 | +\begin{codeblock} |
| 6791 | +try { |
| 6792 | + // ... |
| 6793 | +} catch(const char* p) { |
| 6794 | + // handle character string exceptions here |
| 6795 | +} |
| 6796 | +\end{codeblock} |
| 6797 | +and |
| 6798 | +\begin{codeblock} |
| 6799 | +class Overflow { |
| 6800 | +public: |
| 6801 | + Overflow(char,double,double); |
| 6802 | +}; |
| 6803 | + |
| 6804 | +void f(double x) { |
| 6805 | + throw Overflow('+',x,3.45e107); |
| 6806 | +} |
| 6807 | +\end{codeblock} |
| 6808 | +can be caught by a handler for exceptions of type |
| 6809 | +\tcode{Overflow}: |
| 6810 | +\begin{codeblock} |
| 6811 | +try { |
| 6812 | + f(1.2); |
| 6813 | +} catch(Overflow& oo) { |
| 6814 | + // handle exceptions of type \tcode{Overflow} here |
| 6815 | +} |
| 6816 | +\end{codeblock} |
| 6817 | +\end{example} |
| 6818 | + |
| 6819 | +\pnum |
| 6820 | +\indextext{exception handling!throwing}% |
| 6821 | +\indextext{exception handling!handler}% |
| 6822 | +\indextext{exception handling!nearest handler}% |
| 6823 | +When an exception is thrown, control is transferred to the nearest handler with |
| 6824 | +a matching type\iref{except.handle}; ``nearest'' means the handler |
| 6825 | +for which the |
| 6826 | +\grammarterm{compound-statement} or |
| 6827 | +\grammarterm{ctor-initializer} |
| 6828 | +following the |
| 6829 | +\keyword{try} |
| 6830 | +keyword was most recently entered by the thread of control and not yet exited. |
| 6831 | + |
| 6832 | +\pnum |
| 6833 | +Throwing an exception |
| 6834 | +initializes an object with dynamic storage duration, |
| 6835 | +called the |
| 6836 | +\defnx{exception object}{exception handling!exception object}. |
| 6837 | +If the type of the exception object would be |
| 6838 | +an incomplete type\iref{basic.types.general}, |
| 6839 | +an abstract class type\iref{class.abstract}, |
| 6840 | +or a pointer to an incomplete type other than |
| 6841 | +\cv{}~\keyword{void}\iref{basic.compound}, |
| 6842 | +the program is ill-formed. |
| 6843 | + |
| 6844 | +\pnum |
| 6845 | +\indextext{exception handling!memory}% |
| 6846 | +\indextext{exception handling!rethrowing}% |
| 6847 | +\indextext{exception handling!exception object}% |
| 6848 | +The memory for the exception object is |
| 6849 | +allocated in an unspecified way, except as noted in~\ref{basic.stc.dynamic.allocation}. |
| 6850 | +If a handler exits by rethrowing, control is passed to another handler for |
| 6851 | +the same exception object. |
| 6852 | +The points of potential destruction for the exception object are: |
| 6853 | +\begin{itemize} |
| 6854 | +\item |
| 6855 | +when an active handler for the exception exits by |
| 6856 | +any means other than |
| 6857 | +rethrowing, |
| 6858 | +immediately after the destruction of the object (if any) |
| 6859 | +declared in the \grammarterm{exception-declaration} in the handler; |
| 6860 | + |
| 6861 | +\item |
| 6862 | +when an object of type \tcode{std::exception_ptr}\iref{propagation} |
| 6863 | +that refers to the exception object is destroyed, |
| 6864 | +before the destructor of \tcode{std::exception_ptr} returns. |
| 6865 | +\end{itemize} |
| 6866 | + |
| 6867 | +Among all points of potential destruction for the exception object, |
| 6868 | +there is an unspecified last one |
| 6869 | +where the exception object is destroyed. |
| 6870 | +All other points happen before that last one\iref{intro.races}. |
| 6871 | +\begin{note} |
| 6872 | +No other thread synchronization is implied in exception handling. |
| 6873 | +\end{note} |
| 6874 | +The implementation may then |
| 6875 | +deallocate the memory for the exception object; any such deallocation |
| 6876 | +is done in an unspecified way. |
| 6877 | +\begin{note} |
| 6878 | +A thrown exception does not |
| 6879 | +propagate to other threads unless caught, stored, and rethrown using |
| 6880 | +appropriate library functions; see~\ref{propagation} and~\ref{futures}. |
| 6881 | +\end{note} |
| 6882 | + |
| 6883 | +\pnum |
| 6884 | +\indextext{exception handling!exception object!constructor}% |
| 6885 | +\indextext{exception handling!exception object!destructor}% |
| 6886 | +Let \tcode{T} denote the type of the exception object. |
| 6887 | +Copy-initialization of an object of type \tcode{T} from |
| 6888 | +an lvalue of type \tcode{const T} in a context unrelated to \tcode{T} |
| 6889 | +shall be well-formed. |
| 6890 | +If \tcode{T} is a class type, |
| 6891 | +the selected constructor is odr-used\iref{basic.def.odr} and |
| 6892 | +the destructor of \tcode{T} is potentially invoked\iref{class.dtor}. |
| 6893 | + |
| 6894 | +\pnum |
| 6895 | +An exception is considered uncaught |
| 6896 | +after completing the initialization of the exception object |
| 6897 | +until completing the activation of a handler for the exception\iref{except.handle}. |
| 6898 | +\begin{note} |
| 6899 | +As a consequence, an exception is considered uncaught |
| 6900 | +during any stack unwinding resulting from it being thrown. |
| 6901 | +\end{note} |
| 6902 | + |
| 6903 | +\pnum |
| 6904 | +\indextext{exception handling!rethrow}% |
| 6905 | +\indextext{rethrow|see{exception handling, rethrow}}% |
| 6906 | +An exception is considered caught when a handler for that exception |
| 6907 | +becomes active\iref{except.handle}. |
| 6908 | +\begin{note} |
| 6909 | +An exception can have active handlers and still be considered uncaught if |
| 6910 | +it is rethrown. |
| 6911 | +\end{note} |
| 6912 | + |
| 6913 | +\pnum |
| 6914 | +\indexlibraryglobal{uncaught_exceptions}% |
| 6915 | +If an exception is rethrown\iref{expr.throw,propagation}, |
| 6916 | +it is considered uncaught from the point of rethrow |
| 6917 | +until the rethrown exception is caught. |
| 6918 | +\begin{note} |
| 6919 | +The function \tcode{std::uncaught_exceptions}\iref{uncaught.exceptions} |
| 6920 | +returns the number of uncaught exceptions in the current thread. |
| 6921 | +\end{note} |
| 6922 | + |
| 6923 | +\pnum |
| 6924 | +\indextext{exception handling!terminate called@\tcode{terminate} called}% |
| 6925 | +\indextext{\idxcode{terminate}!called}% |
| 6926 | +If the exception handling mechanism |
| 6927 | +handling an uncaught exception |
| 6928 | +directly invokes a function that exits via an |
| 6929 | +exception, the function \tcode{std::terminate} is invoked\iref{except.terminate}. |
| 6930 | +\begin{example} |
| 6931 | +\begin{codeblock} |
| 6932 | +struct C { |
| 6933 | + C() { } |
| 6934 | + C(const C&) { |
| 6935 | + if (std::uncaught_exceptions()) { |
| 6936 | + throw 0; // throw during copy to handler's \grammarterm{exception-declaration} object\iref{except.handle} |
| 6937 | + } |
| 6938 | + } |
| 6939 | +}; |
| 6940 | + |
| 6941 | +int main() { |
| 6942 | + try { |
| 6943 | + throw C(); // calls \tcode{std::terminate} if construction of the handler's |
| 6944 | + // \grammarterm{exception-declaration} object is not elided\iref{class.copy.elision} |
| 6945 | + } catch(C) { } |
| 6946 | +} |
| 6947 | +\end{codeblock} |
| 6948 | +\end{example} |
| 6949 | +\begin{note} |
| 6950 | +If a destructor directly invoked by stack unwinding exits via an exception, |
| 6951 | +\tcode{std::terminate} is invoked. |
| 6952 | +\end{note} |
| 6953 | + |
| 6954 | +\rSec2[except.ctor]{Stack unwinding}% |
| 6955 | +\indextext{exception handling!constructors and destructors}% |
| 6956 | +\indextext{constructor!exception handling|see{exception handling, constructors and destructors}}% |
| 6957 | +\indextext{destructor!exception handling|see{exception handling, constructors and destructors}} |
| 6958 | + |
| 6959 | +\pnum |
| 6960 | +\indextext{unwinding!stack}% |
| 6961 | +As control passes from the point where an exception is thrown |
| 6962 | +to a handler, |
| 6963 | +objects are destroyed by a process, |
| 6964 | +specified in this subclause, called \defn{stack unwinding}. |
| 6965 | + |
| 6966 | +\pnum |
| 6967 | +Each object with automatic storage duration is destroyed if it has been |
| 6968 | +constructed, but not yet destroyed, |
| 6969 | +since the try block was entered. |
| 6970 | +If an exception is thrown during the destruction of temporaries or |
| 6971 | +local variables for a \keyword{return} statement\iref{stmt.return}, |
| 6972 | +the destructor for the returned object (if any) is also invoked. |
| 6973 | +The objects are destroyed in the reverse order of the completion |
| 6974 | +of their construction. |
| 6975 | +\begin{example} |
| 6976 | +\begin{codeblock} |
| 6977 | +struct A { }; |
| 6978 | + |
| 6979 | +struct Y { ~Y() noexcept(false) { throw 0; } }; |
| 6980 | + |
| 6981 | +A f() { |
| 6982 | + try { |
| 6983 | + A a; |
| 6984 | + Y y; |
| 6985 | + A b; |
| 6986 | + return {}; // \#1 |
| 6987 | + } catch (...) { |
| 6988 | + } |
| 6989 | + return {}; // \#2 |
| 6990 | +} |
| 6991 | +\end{codeblock} |
| 6992 | +At \#1, the returned object of type \tcode{A} is constructed. |
| 6993 | +Then, the local variable \tcode{b} is destroyed\iref{stmt.jump}. |
| 6994 | +Next, the local variable \tcode{y} is destroyed, |
| 6995 | +causing stack unwinding, |
| 6996 | +resulting in the destruction of the returned object, |
| 6997 | +followed by the destruction of the local variable \tcode{a}. |
| 6998 | +Finally, the returned object is constructed again at \#2. |
| 6999 | +\end{example} |
| 7000 | + |
| 7001 | +\pnum |
| 7002 | +If the initialization of an object |
| 7003 | +other than by delegating constructor |
| 7004 | +is terminated by an exception, |
| 7005 | +the destructor is invoked for |
| 7006 | +each of the object's subobjects |
| 7007 | +that were known to be initialized by the object's initialization and |
| 7008 | +whose initialization has completed\iref{dcl.init}. |
| 7009 | +\begin{note} |
| 7010 | +If such an object has a reference member |
| 7011 | +that extends the lifetime of a temporary object, |
| 7012 | +this ends the lifetime of the reference member, |
| 7013 | +so the lifetime of the temporary object is effectively not extended. |
| 7014 | +\end{note} |
| 7015 | +\indextext{subobject!initialized, known to be}% |
| 7016 | +A subobject is \defn{known to be initialized} |
| 7017 | +if it is not an anonymous union member and |
| 7018 | +its initialization is specified |
| 7019 | +\begin{itemize} |
| 7020 | +\item in \ref{class.base.init} for initialization by constructor, |
| 7021 | +\item in \ref{class.copy.ctor} for initialization by defaulted copy/move constructor, |
| 7022 | +\item in \ref{class.inhctor.init} for initialization by inherited constructor, |
| 7023 | +\item in \ref{dcl.init.aggr} for aggregate initialization, |
| 7024 | +\item in \ref{expr.prim.lambda.capture} for the initialization of |
| 7025 | +the closure object when evaluating a \grammarterm{lambda-expression}, |
| 7026 | +\item in \ref{dcl.init.general} for |
| 7027 | +default-initialization, value-initialization, or direct-initialization |
| 7028 | +of an array. |
| 7029 | +\end{itemize} |
| 7030 | +\begin{note} |
| 7031 | +This includes virtual base class subobjects |
| 7032 | +if the initialization |
| 7033 | +is for a complete object, and |
| 7034 | +can include variant members |
| 7035 | +that were nominated explicitly by |
| 7036 | +a \grammarterm{mem-initializer} or \grammarterm{designated-initializer-clause} or |
| 7037 | +that have a default member initializer. |
| 7038 | +\end{note} |
| 7039 | +If the destructor of an object is terminated by an exception, |
| 7040 | +each destructor invocation |
| 7041 | +that would be performed after executing the body of the destructor\iref{class.dtor} and |
| 7042 | +that has not yet begun execution |
| 7043 | +is performed. |
| 7044 | +\begin{note} |
| 7045 | +This includes virtual base class subobjects if |
| 7046 | +the destructor was invoked for a complete object. |
| 7047 | +\end{note} |
| 7048 | +The subobjects are destroyed in the reverse order of the completion of |
| 7049 | +their construction. Such destruction is sequenced before entering a |
| 7050 | +handler of the \grammarterm{function-try-block} of the constructor or destructor, |
| 7051 | +if any. |
| 7052 | + |
| 7053 | +\pnum |
| 7054 | +If the \grammarterm{compound-statement} |
| 7055 | +of the \grammarterm{function-body} |
| 7056 | +of a delegating constructor |
| 7057 | +for an object exits via |
| 7058 | +an exception, the object's destructor is invoked. |
| 7059 | +Such destruction is sequenced before entering a handler of the |
| 7060 | +\grammarterm{function-try-block} of a delegating constructor for that object, if any. |
| 7061 | + |
| 7062 | +\pnum |
| 7063 | +\begin{note} |
| 7064 | +If the object was allocated by a \grammarterm{new-expression}\iref{expr.new}, |
| 7065 | +the matching deallocation function\iref{basic.stc.dynamic.deallocation}, |
| 7066 | +if any, is called to free the storage occupied by the object. |
| 7067 | +\end{note} |
| 7068 | + |
6763 | 7069 | \rSec2[basic.start]{Start and termination}
|
6764 | 7070 |
|
6765 | 7071 | \rSec3[basic.start.main]{\tcode{main} function}
|
|
0 commit comments