shared_ptr 没有 RTTI?
shared_ptr without RTTI?
我正在尝试在使用 xc32 1.34(gcc 4.5.2 的衍生版本)构建的嵌入式项目中使用 shared_ptr
。该项目已使用 -fno-rtti
禁用 RTTI。
#include <memory>
仅包含 header 就会出现以下错误:
/Applications/microchip/xc32/v1.34/bin/bin/../../lib/gcc/pic32mx/4.5.2/../../../../pic32mx/include/Cpp/memory: In member function 'virtual void* std::tr1::_Ref_count_del<_Ty, _Dx>::_Get_deleter(const std::type_info&) const':
In file included from APP/MODULES/LIGHT_MANAGER/LightManager.cpp:13:0:
/Applications/microchip/xc32/v1.34/bin/bin/../../lib/gcc/pic32mx/4.5.2/../../../../pic32mx/include/Cpp/memory:1264:39: error: cannot use typeid with -fno-rtti
/Applications/microchip/xc32/v1.34/bin/bin/../../lib/gcc/pic32mx/4.5.2/../../../../pic32mx/include/Cpp/memory: In member function 'virtual void* std::tr1::_Ref_count_del_alloc<_Ty, _Dx, _Alloc>::_Get_deleter(const std::type_info&) const':
/Applications/microchip/xc32/v1.34/bin/bin/../../lib/gcc/pic32mx/4.5.2/../../../../pic32mx/include/Cpp/memory:1299:39: error: cannot use typeid with -fno-rtti
/Applications/microchip/xc32/v1.34/bin/bin/../../lib/gcc/pic32mx/4.5.2/../../../../pic32mx/include/Cpp/memory: In function '_Dx* std::tr1::get_deleter(const std::tr1::shared_ptr<_Ty2>&)':
/Applications/microchip/xc32/v1.34/bin/bin/../../lib/gcc/pic32mx/4.5.2/../../../../pic32mx/include/Cpp/memory:1956:44: error: cannot use typeid with -fno-rtti
所以我想知道的是:如果没有 RTTI,通常无法使用 shared_ptr
,还是我做错了什么?
问题是 get_deleter
自由函数:
template<class D, class T> D* get_deleter(const shared_ptr<T>& p) noexcept;
Returns: If p
owns a deleter d
of type cv-unqualified D
, returns std:addressof(d)
; otherwise returns nullptr
. The returned pointer remains valid as long as there exists a shared_ptr
instance that owns d
.
显然,最直接的实现是将删除器的typeid
存储在控制块中。虽然还有其他可能的实现,但它们会 (a) 更复杂,(b) 失去与启用 RTTI 的代码的二进制兼容性,以及 (c) 反对 -fno-rtti
.[=33= 的 "spirit" ]
另一个有问题的函数是 dynamic_pointer_cast
,它在存储的指针上调用 dynamic_cast
。
然而,shared_ptr
的主要功能可以在不使用 RTTI 功能的情况下实现,实际上正如 Sergei Nikulov 上面提到的那样,gcc 4.8.5 附带的 shared_ptr
可以与 -fno-rtti
,get_deleter
和 dynamic_pointer_cast
函数除外;只要您不使用这些设施,就没有理由不能使用 shared_ptr
。这可以与例如对比any
,不使用 typeid
.
是无法实现的
您的供应商有责任提供适用于其编译器所有配置的标准库,包括支持其使用的非标准库。但是,如果您的供应商不合作,您仍然有几个选择:
- 修补提供的标准库以删除损坏的
get_deleter
代码;
- 使用替代标准库(例如更新的 libstdc++ 或 libc++);
- 使用替代的智能指针工具(例如 Boost)或自己编写一个。
我正在尝试在使用 xc32 1.34(gcc 4.5.2 的衍生版本)构建的嵌入式项目中使用 shared_ptr
。该项目已使用 -fno-rtti
禁用 RTTI。
#include <memory>
仅包含 header 就会出现以下错误:
/Applications/microchip/xc32/v1.34/bin/bin/../../lib/gcc/pic32mx/4.5.2/../../../../pic32mx/include/Cpp/memory: In member function 'virtual void* std::tr1::_Ref_count_del<_Ty, _Dx>::_Get_deleter(const std::type_info&) const':
In file included from APP/MODULES/LIGHT_MANAGER/LightManager.cpp:13:0:
/Applications/microchip/xc32/v1.34/bin/bin/../../lib/gcc/pic32mx/4.5.2/../../../../pic32mx/include/Cpp/memory:1264:39: error: cannot use typeid with -fno-rtti
/Applications/microchip/xc32/v1.34/bin/bin/../../lib/gcc/pic32mx/4.5.2/../../../../pic32mx/include/Cpp/memory: In member function 'virtual void* std::tr1::_Ref_count_del_alloc<_Ty, _Dx, _Alloc>::_Get_deleter(const std::type_info&) const':
/Applications/microchip/xc32/v1.34/bin/bin/../../lib/gcc/pic32mx/4.5.2/../../../../pic32mx/include/Cpp/memory:1299:39: error: cannot use typeid with -fno-rtti
/Applications/microchip/xc32/v1.34/bin/bin/../../lib/gcc/pic32mx/4.5.2/../../../../pic32mx/include/Cpp/memory: In function '_Dx* std::tr1::get_deleter(const std::tr1::shared_ptr<_Ty2>&)':
/Applications/microchip/xc32/v1.34/bin/bin/../../lib/gcc/pic32mx/4.5.2/../../../../pic32mx/include/Cpp/memory:1956:44: error: cannot use typeid with -fno-rtti
所以我想知道的是:如果没有 RTTI,通常无法使用 shared_ptr
,还是我做错了什么?
问题是 get_deleter
自由函数:
template<class D, class T> D* get_deleter(const shared_ptr<T>& p) noexcept;
Returns: If
p
owns a deleterd
of type cv-unqualifiedD
, returnsstd:addressof(d)
; otherwise returnsnullptr
. The returned pointer remains valid as long as there exists ashared_ptr
instance that ownsd
.
显然,最直接的实现是将删除器的typeid
存储在控制块中。虽然还有其他可能的实现,但它们会 (a) 更复杂,(b) 失去与启用 RTTI 的代码的二进制兼容性,以及 (c) 反对 -fno-rtti
.[=33= 的 "spirit" ]
另一个有问题的函数是 dynamic_pointer_cast
,它在存储的指针上调用 dynamic_cast
。
然而,shared_ptr
的主要功能可以在不使用 RTTI 功能的情况下实现,实际上正如 Sergei Nikulov 上面提到的那样,gcc 4.8.5 附带的 shared_ptr
可以与 -fno-rtti
,get_deleter
和 dynamic_pointer_cast
函数除外;只要您不使用这些设施,就没有理由不能使用 shared_ptr
。这可以与例如对比any
,不使用 typeid
.
您的供应商有责任提供适用于其编译器所有配置的标准库,包括支持其使用的非标准库。但是,如果您的供应商不合作,您仍然有几个选择:
- 修补提供的标准库以删除损坏的
get_deleter
代码; - 使用替代标准库(例如更新的 libstdc++ 或 libc++);
- 使用替代的智能指针工具(例如 Boost)或自己编写一个。