【发布时间】:2021-01-07 18:30:53
【问题描述】:
我有一些代码期望在共享库中创建的特定类型的 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++),但没有得到相同的行为。我也尝试过定义和不定义_LIBCPP_NONUNIQUE_RTTI_BIT。
所以,我假设这是链接器而不是编译器的结果。这是真的吗?
GCC 编译器在跨共享库边界在 Linux 上进行这项工作是否“太有帮助”?
【问题讨论】:
-
您需要确保类型的 rtti 信息是从其中一个共享库中导出的,这样每个库就不会以自己的副本结束