问题描述
我有一些代码期望在共享库中为特定类型创建的type_index
实例与在可执行文件中(对于相同特定类型)创建的实例进行比较。
但是,我遇到了在QNX 7上不起作用的情况:
// idxlib.h
#include <typeindex>
#include <string>
#include <iostream>
#ifdef BUILD_LIB
#define LIB_EXPORT __attribute__((visibility("default")))
#else
#define LIB_EXPORT
#endif
template <typename T>
class Templ
{
};
class LIB_EXPORT LibType
{
public:
LibType();
template <typename T=int>
void templateMethod(int arg = 0) const
{
#ifndef REMOVE_INSTANTIATION
if (arg == 42)
{
// arg is never 42. This code path is not taken,but it instantiates the template
templateMethod();
}
#endif
if (mti == std::type_index(typeid(Templ<int>)))
std::cout << "Type indexes the same" << std::endl;
else
std::cout << "Type indexes NOT the same" << std::endl;
}
void normalMethod();
protected:
std::type_index mti;
};
// idxlib.cpp
#include "idxlib.h"
LibType::LibType() : mti(std::type_index(typeid(Templ<int>))) {}
void LibType::normalMethod()
{
templateMethod();
}
// sharedidx.cpp
#include "idxlib.h"
int main(int argc,char* argv[])
{
LibType lt;
if (argc == 65)
// argc is not 65,so don't call it,just instantiate it
lt.templateMethod();
lt.normalMethod();
return 0;
}
构建,SCP和运行:
QCC -Vgcc_ntox86_64 -g -fPIC -o idxlib.cpp.o -c idxlib.cpp -DBUILD_LIB -fvisibility=hidden -fvisibility-inlines-hidden
QCC -Vgcc_ntox86_64 -g -shared -o libidx.so idxlib.cpp.o
QCC -Vgcc_ntox86_64 -g -o sharedidx libidx.so sharedidx.cpp
scp -i ~/qnxinstall/id_rsa_qnx sharedidx libidx.so qnxuser@${QNXBox}:/home/qnxuser/test
echo
echo "comparison fails:"
ssh -i ~/qnxinstall/id_rsa_qnx -t qnxuser@${QNXBox} "cd /home/qnxuser/test && LD_LIBRARY_PATH=/home/qnxuser/test ./sharedidx"
QCC -Vgcc_ntox86_64 -g -shared -fPIC -o idxlib.cpp.o -c idxlib.cpp -DREMOVE_INSTANTIATION -DBUILD_LIB -fvisibility=hidden -fvisibility-inlines-hidden
QCC -Vgcc_ntox86_64 -g -shared -o libidx.so idxlib.cpp.o
QCC -Vgcc_ntox86_64 -g -o sharedidx libidx.so -DREMOVE_INSTANTIATION sharedidx.cpp -fvisibility=hidden -fvisibility-inlines-hidden
scp -i ~/qnxinstall/id_rsa_qnx sharedidx libidx.so qnxuser@${QNXBox}:/home/qnxuser/test
echo
echo "comparison works:"
ssh -i ~/qnxinstall/id_rsa_qnx -t qnxuser@${QNXBox} "cd /home/qnxuser/test && LD_LIBRARY_PATH=/home/qnxuser/test ./sharedidx"
输出:
Type indexes NOT the same
Type indexes the same
因此,当存在包含自身模板实例化的模板实例化时,type_index比较将失败。
这是QNX 7中的错误,还是我的期望(应该可以正常工作)是错误的?
此代码是否依赖于实现定义的行为?还是不确定的行为?
QNX 7 QCC编译器基于GCC 5.4,并使用基于同一时代的libc ++的标准库。我已经在Linux上测试了GCC 5.4(以及带有libc ++和libstdc ++的clang),但没有得到相同的行为。在没有定义_LIBCPP_NONUNIQUE_RTTI_BIT
的情况下,我也尝试过。
所以,我假设这是链接器而不是编译器的结果。可以吗?
GCC编译器在跨共享库边界在Linux上进行这项工作时是否只是“太有用了”?
解决方法
我永远不会假设RTTI在针对工具链的嵌入式系统上可以正常工作。它可能应该正常工作,但是几乎没有人为嵌入式系统启用RTTI或异常,因此它将得到零测试,也不会得到支持的关注。
我建议您使用基于库的RTTI仿真,例如https://www.boost.org/doc/libs/1_74_0/doc/html/boost_typeindex.html,它可以在没有RTTI的系统上运行,并且与语言RTTI一样,具有完全确定性,并且在空间和时间上都有局限性。