我从一个共享库中抛出一个异常并将其捕获到另一个中。我控制所有源代码,所以应该没问题,我使用 g++4.4.5。首先,以下代码不起作用:
try
{
// do something that throws tags::out_of_range in the other shared lib
}
catch(const tags::out_of_range& e)
{
cout << "out_of_range " << typeid(tags::out_of_range()).name() << endl;
cout << "out of range exception " << typeid(e).name() << endl;
}
catch (const exception& e2)
{
cout << "out_of_range " << typeid(tags::out_of_range()).name() << endl;
cout << "other exception " << typeid(e2).name() << endl;
}
我总是最终只捕获一个 std::exception。打印代码中看到的 typeid().name() 给出了可能的解释:
超出范围 FN4tags12out_of_rangeEvE
其他异常 N4tags12out_of_rangeE
我们可以看到名称不匹配,如果我理解正确,当类位于不同的模块中时,名称实际上是字符串比较的动态转换。
所以在某处我读到尝试添加 -fPIC,突然它起作用了(意味着我发现了一个 out_of_range 异常),尽管打印名称仍然给出相同的结果。我认为与位置无关的代码不再重要,并查看有关 -fPIC 的 g++ 手册页:
“此选项在 m68k、PowerPC 和 SPARC 上有所不同”
我使用的是 x86-64。在这种情况下,我真的看不出代码定位有何不同?此外,如果 typeid 名称是字符串比较,我认为我仍然会在 std::exception 子句中结束,因为即使使用 -fPIC 它们仍然不同?
所以问题是:为什么 -fPIC 有什么不同?