is valid exception handler, t class non-const member function func?
in other words: catch guaranteed bind directly (modifiable) exception object, or there latitude compiler trickery when catch const reference?
catch(const t &t) { const_cast<t &>(t).func(); }
from [except.throw]:
evaluating throw-expression operand throws exception (15.1); type of exception object determined removing top-level cv-qualifiers static type of operand , adjusting type “array of t” or “function returning t” “pointer t” or “pointer function returning t”, respectively.
and, emphasis mine:
throwing exception copy-initializes (8.5, 12.8) temporary object, called exception object. temporary lvalue , used initialize variable declared in matching handler (15.3).
so if throw operand of type cv t, we're copy-initializing temporary object of type t.
then according [except.handle], handler const t& (for non-pointer-type t) matched exception object of type e if:
- [...] e , t same type (ignoring top-level cv-qualifiers),
- [...] t unambiguous public base class of e
this handler initialized by:
the variable declared exception-declaration, of type cv t or cv t&, initialized exception object, of type e, follows:
— if t base class of e, variable copy-initialized (8.5) corresponding base class subobject of exception object;
— otherwise, variable copy-initialized (8.5) exception object.
so if catch const t&, we're copy-initializing reference exception object - know previous section either of type t or derived publicly t. [dcl.init.ref]:
a reference type “cv1 t1” initialized expression of type “cv2 t2” follows:
— if reference lvalue reference , initializer expression
— lvalue (but not bit-field), , “cv1 t1” reference-compatible “cv2 t2”, or [...]then reference bound initializer expression lvalue in first case
the key temporary exception object still lvalue. thus, if our handler matched const t&, know reference bound directly object of type t or d (where d derives t) - either way, it's type reference-compatible const t. such, there no undefined behavior. if temporary object rvalue or handler match wider range of types, temporary created of type const t - , const_cast undefined behavior.
while code exhibits no undefined behavior on conforming compiler, there's no reason not do:
catch(t &t) { t.func(); }
Comments
Post a Comment