【问题标题】:What does "break when an exception is void" mean?“异常无效时中断”是什么意思?
【发布时间】:2013-01-09 17:16:52
【问题描述】:

我发现 Visual C++ 2010 的自动中断异常功能在过去非常有用,今天我查看了此对话框中的选项,发现其中一种异常类型是“void”。这是什么意思?如果我选择这个,我会在代码中抛出的任何异常上中断吗?如果不是,什么样的 throw 语句会触发这种类型的断点?

我想一个更一般的后续问题是我在哪里可以找到有关此对话框及其所有选项的文档?

【问题讨论】:

  • 我的第一个赌注是:它意味着任何不是从任何其他异常(包括throw 5;)派生的类型的代理。一个简短的测试表明:事实并非如此 - 期待答案......
  • 只是好奇:您是否设法让它在调试器中捕获“void”异常?
  • @doug65536 好吧,有趣的是,如果我使用了 void*,我正要让它工作,但这似乎不是它的预期用途。

标签: c++ visual-studio-2010 visual-c++ exception


【解决方案1】:

关于它是如何工作的(正如 MSalters 所提到的),这只是不正确的命名。

其实应该命名为void*,当然。

但为什么它适用于int*const char* 等(实际上是任何指针类型,包括指向用户定义类型的指针)?

好吧,我可以假设这与非常有趣的 C++ 异常处理问题有关 - catch(void*) 异常处理程序实际上捕获了任何(cv 兼容的)指针类型异常

例子:

try
{
   throw "Catch me if you can!";      
}
catch(void* e)
{
   // ...and I can!
   std::cout << "Gotcha!" << std::endl;
}

在这里,我们抛出 char*(在 Visual C++ 中,字符文字是 char*,而不是 const char*)并被 void* 捕获。它会起作用的!

答案可以在C++神圣标准中找到:

§15.3 处理异常

15.3.3 处理程序匹配 E 类型的异常对象 if

...

处理程序的类型为 cv1 T* cv2 并且 E 是指针类型,可以通过以下两者之一或两者转换为处理程序的类型 — 标准指针转换 (4.10),不涉及到指向私有或受保护或不明确类的指针的转换

...

4.10 说标准指针转换包括转换为void*

4.10.2 “pointer to cv T”类型的纯右值,其中 T 是一个对象类型,可以转换为“pointer”类型的纯右值 到 cv void”。

另请注意,Visual Studio 调试器的工作方式类似,但不完全是这种方式。不同之处在于它忽略了 cv 限定符。所以“异常”对话框中的void 实际上意味着任何[any cv] void*。捕获处理程序将不会忽略它们:

try
{
   struct Throwee {};
   const Throwee* t = nullptr;
   throw t;      
}
catch(void* e)
{
   // Will be missed
   std::cout << "Gotcha!" << std::endl;
}
catch(const void* e)
{
   // Will be catched
   std::cout << "Gotcha const!" << std::endl;
}

【讨论】:

  • 优秀。这正是我一直在寻找的。谢谢!
【解决方案2】:

我发现抛出void*int*char const* 时它会中断,但int 不会。

【讨论】:

    【解决方案3】:

    这可能是 catch (...) 的设置。要么传播throw; 语句。

    【讨论】:

    • 不,不是这样。一个简单的测试证实我不是这种情况。
    • 而在 catch 块之外的 throw; 会导致未处理的异常,因为它是结构化异常,所以 catch(...) 不会捕获该异常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-23
    • 2013-11-08
    • 1970-01-01
    • 1970-01-01
    • 2012-02-12
    • 1970-01-01
    相关资源
    最近更新 更多