什么例外可以“尝试捕获(...)”在c ++中捕获?

时间:2016-02-28 04:46:46

标签: c++ visual-studio visual-c++ try-catch

代码

    try{
        memcpy(p, buf, l);
    }
    catch (...){
        ofstream f("memcpy.error");
        f << "memcpy.error";
    }

如果p为null,memcpy将抛出异常,但catch(...)无法捕获它。所以,在c ++中,try catch(...)实际上做了什么?

3 个答案:

答案 0 :(得分:3)

通过暗示将问题标记为[visual-studio]和[winapi]来回答。

try/catch阻止捕获C++个异常,而具有NULL目标的memcpy会抛出 Win32结构化异常

您可以使用__try/__except块(Structured Exception Handling)来捕获这些例外。

或者,您可以通过_set_se_translator将它们转换为可在C ++ try/catch块中捕获的C ++异常。

答案 1 :(得分:2)

RE

  

什么例外可以”尝试捕获(...)“在c ++中捕获?

它可以捕获C ++ throw生成的任何异常。

请注意,省略号...需要三个句点,而不是Unicode 省略号字符,否则编译器会阻塞它!

重新编码

buf = nullptr;
try{
    memcpy(p, buf, l);
}
catch (...){
    ofstream f("memcpy.error");
    f << "memcpy.error";
}

memcpy here has formal undefined behavior的电话。

但是,特定的C ++实现可以定义任何行为,包括正式的UB,并且您的编译器Visual C ++可以使用特殊选项来实现。但是,Microsoft's documentation of memcpy没有提到这种更明确的行为。

第三方面,未定义的行为包括您可能会得到一些您错误预期的行为,例如执行进入catch子句。

在1990年代,默认情况下,Microsoft的Visual C ++会在catch(...)中捕获Windows SEH异常(较低级别的异常)。例如,您可以通过取消引用nullpointer来获取SEH异常,这可能会在memcpy调用中发生。令人高兴的是,编译器不再捕获默认的此类异常,但您可以使用_set_se_translator函数指定该行为。

答案 2 :(得分:1)

  

如果p为空,memcpy将抛出异常。

不正确的。如果任一指​​针为null,则它是未定义的行为。由于undefined是“未定义的”,因此当它发生时,你可以做很多事情(以非实现依赖的方式)。