c++ - C++ 最简单的 RTTI 实现是什么?

标签 c++ exception-handling rtti

我正在尝试为嵌入式操作系统实现异常处理,但我对如何检测抛出的“异常”类型(以选择适当的处理程序)感到困惑。

异常处理的保存和恢复上下文部分已经完成,但我不能有特定的句柄,因为我无法检测到抛出的“异常”的类型。 c++ 的标准 RTTI 实现过于依赖其他库,因此我目前认为它不可用。

考虑到我的目标是嵌入式系统,因此我不能创建太多代码,我可以获得(或制作)的“运行时类型信息”的最小实现是什么?

-- 编辑--

我不是在研究编译器,它是 ia32-g++。

最佳答案

当您在嵌入式环境中工作时,您可能更喜欢极简的解决方案,并且可以利用有关编译器的非标准或不可移植的事实。

如果一个类在 C++ 中是多态的(至少有一个自己的虚函数),它可能有一个指向嵌入其中某处的 vtable 的指针。可能是 vtable 指针出现在内存中对象布局的开头。

许多编译器都是如此,它们使用 C++ ABI - a related SO question here .

如果是这样,您可能能够像这样访问 vtable:

void *get_vtable(void *obj)
{
    return *(reinterpret_cast<void **>(obj));
}

然后你可以比较两个指向对象的指针的虚表,看看它们是否指向同一类型的对象。

所以“类型转换”(基本上就是 catch)会做这样的事情:

P p;
Q q;
if (get_vtable(caught) == get_vtable(&p))
{
    // it's a P...
}
else if (get_vtable(caught) == get_vtable(&q))
{
    // it's a Q...
}

您可以在 CATCH 宏中隐藏该模式。

要点 - 如果您从基类派生类,但派生类没有覆盖任何虚函数或添加任何新的虚函数,那么编译器可能会重用基类的 vtable派生类。这意味着为了区分两种异常类型,它们必须各自覆盖一个虚函数,以确保它们有自己的 vtable。

请注意,这只是异常处理涉及的一小部分。还有展开堆栈的小问题!跳转到处理程序时需要调用栈上所有对象的析构函数。这不仅仅是执行 setjmp/longjmp 的问题。

关于c++ - C++ 最简单的 RTTI 实现是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1080953/

相关文章:

c++ - 返回一个 std::array

C++琐碎的try-catch导致中止

c++ - 关于 C++ 中的结构化异常 (SEH),我应该了解什么?

delphi - 当我的值是字符串时,如何为非字符串属性调用 TRttiProperty.SetValue?

delphi - 如何使用delphi 2010 rtti设置数组长度

c++ - 将 std::shared_ptr 与 clang++ 和 libstdc++ 一起使用

c++ - 根据 C 标准,fprintf、fputs...在 Windows 上的功能是否合法?

jsp - JSP Servlet 中的最佳实践错误处理

ios - xCode - 来自苹果崩溃报告服务的崩溃报告的异常原因

c++ - 为什么在使用 typeid 运算符时需要#include <typeinfo>?