三大主流C++编译器引用捕获转换临时对象的合规性疑问
C++编译器异常捕获行为的疑问
int main() { int i = 42; try { throw &i; } catch (void*&) { puts("incorrectly hit?"); } catch (...) {} try { throw nullptr; } catch (void*&) { puts("incorrectly hit?"); } catch (...) {} }
这段代码中,抛出的异常对象类型分别是int*和std::nullptr_t,但catch (void*&)分支却被命中了。唯一的可能性是运行时从异常对象类型转换生成了临时的void*对象,那么catch处理中的void*&必然绑定到这个临时对象,而非实际的异常对象?
查阅C++标准条款[except.handle]:
处理函数与类型为
E的异常对象匹配的情况包括:
- 处理函数类型为
cv T或cv T&,且E与T为相同类型(忽略顶层cv限定符);- 处理函数类型为
cv T或cv T&,且T是E的明确公共基类;- 处理函数类型为
cv T或const T&,T为指针或成员指针类型,E是可通过标准指针转换为T的指针或成员指针类型;- 处理函数类型为
cv T或const T&,T为指针或成员指针类型,且E是std::nullptr_t。
上述条款似乎均不适用当前情况。那么三大主流C++厂商允许该catch处理命中的行为是否违反标准?[except.handle]条款并非新增,2016年还经CWG2093修订,其源自2012年左右的CWG388与CWG729。
CWG388的决议提到“此决议需要修改ABI”,这是否意味着三大厂商从未落实该决议?
(补充:条款[except.handle]/15指出:“当处理函数声明对象的引用时,对引用对象的修改即对异常对象的修改,重新抛出时会生效”——但当引用绑定到转换临时对象时显然不成立,建议在“reference”前添加“non-const”修饰词。)
内容的提问来源于stack exchange,提问作者Quuxplusone
相关产品推荐
相关产品推荐

