是否可以保证一个类型的多个type_index实例比较相等?

问题描述

我有一些代码期望在共享库中为特定类型创建的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一样,具有完全确定性,并且在空间和时间上都有局限性。