我发现 Visual C++ 2010 的自动中断异常功能在过去非常有用,今天我查看了此对话框中的选项,发现其中一种异常类型是“void”。这是什么意思?如果我选择这个,我会在代码中抛出的任何异常上中断吗?如果不是,什么样的 throw 语句会触发这种类型的断点?
我想一个更一般的后续问题是我在哪里可以找到有关此对话框及其所有选项的文档?
我发现 Visual C++ 2010 的自动中断异常功能在过去非常有用,今天我查看了此对话框中的选项,发现其中一种异常类型是“void”。这是什么意思?如果我选择这个,我会在代码中抛出的任何异常上中断吗?如果不是,什么样的 throw 语句会触发这种类型的断点?
我想一个更一般的后续问题是我在哪里可以找到有关此对话框及其所有选项的文档?
关于它是如何工作的(正如 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++ Holy Standard 中找到:
§15.3 处理异常
15.3.3 处理程序是 E 类型异常对象的匹配项,如果
...
处理程序的类型为 cv1 T* cv2 并且 E 是指针类型,可以通过以下任一或两者转换为处理程序的类型 — 标准指针转换 (4.10),不涉及到指向私有或受保护或不明确类的指针的转换
...
并且 4.10 说标准指针转换包括转换为void*
:
4.10.2 “指向 cv T 的指针”类型的纯右值,其中 T 是对象类型,可以转换为“指向 cv void 的指针”类型的纯右值。
另请注意,Visual Studio 调试器的工作方式类似,但并非完全如此。不同之处在于它忽略了 cv 限定符。所以void
在 Exceptions 对话框中实际上意味着任何[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;
}
我发现它会在抛出void*
,int*
或时打破char const*
,但不是int
。
这可能是 catch (...) 的设置。要么传播throw;
声明。