【发布时间】:2012-12-16 15:33:21
【问题描述】:
我看到一个奇怪的故障,dynamic_cast 在 clang 编译器上返回 NULL。但是相同的代码适用于 gcc 环境。
能否请您指出可能的根本原因是什么? llvm 和 gcc 上的dynamic_cast 之间可能有什么区别。
我正在使用我认为默认启用 RTTI 的两个编译器的默认行为。
template<typename T> T*
find_msg_of_type(
MsgList *list
) {
T* msg = NULL;
if (list) {
for (std::vector<MsgList*>::iterator it = list->element.begin();
it != list->element.end();
it++) {// MsgList can be list of objects build with GSoap.
if (typeid(*(*it)) == typeid(T)) {
msg = dynamic_cast<T*>(*it); // Failing on clang but this same code is working with gcc compiler.
break;
}
}
}
return msg;
}
另一个观察:使用 gcc
if (typeid(*(*it)) == typeid(T))
按预期完美运行,但使用叮当声
if (typeid(*(*it)) == typeid(T))
比较显示出不同的行为。不知道为什么会有所不同。
谢谢
【问题讨论】:
-
这可能是很多事情。您确定两个编译器中的类型相同吗?并且在两个编译器中都有虚拟方法表吗?两个编译器都启用了 RTTI 吗?尝试将问题简化为一个小示例,并将其与使用的编译器命令一起发布。
-
不要在 cmets 中写,编辑问题!应始终将其他详细信息添加到问题正文中。这就是为什么它们是可编辑的!
-
尝试在调试消息中打印
typeid(**it)和typeid(T)——以及typeid(*it)和typeid(T*)。还将dynamic_cast移出条件并检查它是否返回NULL——动态转换在内部进行typeid 比较,但它也接受后代实例。 -
我已经打印了 typeid(*(*it)).name() 和 typeid(T).name(),两者都是相同的,甚至在将 dynamic_cast 移出条件后我也进行了检查.我清楚地表明 dynamic_cast 只返回 NULL。不知道具体为什么!还有一点供您参考,MsgList 将保存 msg,它将在运行时使用 GSoap 构建。我不明白它有什么不同,因为我看到相同的代码可以完美地使用 gcc。
-
您使用的每个编译器的版本是什么?你在哪个平台和平台版本上?当您说“比较表现出不同的行为”时,这种不同的行为是什么?
标签: c++ compilation llvm clang dynamic-cast