c – 是否通过引用捕获异常危险?

请查看以下异常抛出和捕获:

void some_function() {
    throw std::exception("some error message");
}

int main(int argc, char **argv) {
    try {
        some_function();
    } catch (const std::exception& e) {
        std::cerr << e.what() << std::endl;
        exit(1);
    }
    return 0;
}

通过引用捕获抛出的异常是安全的吗?

我的关注是因为异常e实际上放在some_function()的堆栈上。但some_function()刚刚返回,导致e被破坏。所以实际上现在e指向一个破坏的对象。

我的关注是正确的吗?

什么是传递异常而不通过值复制的正确方法?我应该抛出新的std :: exception(),因此它被放置在动态内存?

它确实是安全的 – 并且推荐 – 通过const引用捕获。

e is actually placed on the stack of some_function()

不是不是…实际抛出的对象是在异常处理机制所使用的未指定的内存区域中创建的:

[except.throw] 15.1/4: The memory for the exception object is allocated in an unspecified way, except as noted in 3.7.4.1. The exception
object is destroyed after either the last remaining active handler for the exception exits by any means other than rethrowing, or the last object of type std::exception_ptr (18.8.5) that refers to the exception object is destroyed, whichever is later.

如果一个局部变量被指定为throw,它被复制到那里,如果必要的话(优化器可能能够直接在这个其他内存中创建它)。这就是为什么…

15.1/5 When the thrown object is a class object, the constructor selected for the copy-initialization and the destructor
shall be accessible, even if the copy/move operation is elided (12.8).

如果没有点击,它可能有助于想象这样模糊的实现像这样:

// implementation support variable...
thread__local alignas(alignof(std::max_align_t))
    char __exception_object[EXCEPTION_OBJECT_BUFFER_SIZE];

void some_function() {
    // throw std::exception("some error message");

    // IMPLEMENTATION PSEUDO-CODE:
    auto&& thrown = std::exception("some error message");
    // copy-initialise __exception_object...
    new (&__exception_object) decltype(thrown){ thrown };
    throw __type_of(thrown);
    // as stack unwinds, _type_of value in register or another
    // thread_local var...
}

int main(int argc, char **argv)
{
    try {
        some_function();
    } // IMPLEMENTATION:
      // if thrown __type_of for std::exception or derived...
      catch (const std::exception& e) {
        // IMPLEMENTATION:
        // e references *(std::exception*)(&__exception_object[0]);
        ...
    }
}
http://stackoverflow.com/questions/33387545/is-catching-an-exception-by-reference-dangerous

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:c – 是否通过引用捕获异常危险?