没有RTTI的shared_ptr? [英] shared_ptr without RTTI?

查看:153
本文介绍了没有RTTI的shared_ptr?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在一个嵌入式项目中使用 shared_ptr ,该项目使用xc32 1.34(gcc 4.5.2的派生版)构建。该项目通过 -fno-rtti 禁用RTTI。

  #include< memory> 

只包含标题给了我以下错误:

  /Applications/microchip/xc32/v1.34/bin/bin /../../ lib / gcc / pic32mx / 4.5.2 /../../ ../../pic32mx/include/Cpp/memory:在成员函数'virtual void * std :: tr1 :: _ Ref_count_del <_Ty,_Dx> :: _ Get_deleter(const std :: type_info&)const'中:
从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:can not use typeid with -fno-rtti
/ Applications / microchip / xc32 / v1 .34 / bin / bin /../../ lib / gcc / pic32mx / 4.5.2 /../../../../ pic32mx / include / Cpp / memory:在成员函数'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:错误:无法使用typ eid with -fno-rtti
/Applications/microchip/xc32/v1.34/bin/bin/../../lib/gcc/pic32mx/4.5.2/../../../ ../pic32mx/include/Cpp/memory:函数'_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 :不能使用typeid和-fno-rtti

所以我想知道的是:它通常是不可能的使用 shared_ptr 没有RTTI,或者我做错了什么?

>问题是 get_deleter 免费函数:


 模板< class D,class T> D * get_deleter(const shared_ptr< T& p)noexcept; 

返回:如果 p 拥有 cv -unqualified D 类型的删除器 d ,返回 STD:addressof(d);否则返回 nullptr 。只要存在拥有 d shared_ptr 实例,返回的指针仍然有效。


显然,最直接的实现是将删除器的 typeid 存储在控制块中。虽然还有其他可能的实现,但它们会(a)更复杂,(b)与启用RTTI的代码失去二进制兼容性,(c)违反 -fno-rtti < code $。

另一个有问题的函数是 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 。这可以与例如任何,如果不使用 typeid ,则无法实现。



供应商有责任提供一个标准库,用于编译器的所有配置,包括支持其使用的非标准库。但是,如果您的供应商不合作,您仍然有几个选择:


  • 修补提供的标准库以删除损坏的 get_deleter code;

  • 使用替代标准库(例如更新的libstdc ++或libc ++); 智能指针设施(例如Boost)或自己写一个。

Im trying to use shared_ptr in an embedded project which is build with xc32 1.34 (a derivative of gcc 4.5.2). The project has RTTI disabled with -fno-rtti.

#include <memory>

Just including the header gives me the following errors:

/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

So what i want to know is: is it generally impossible to use shared_ptr without RTTI, or am I doing something wrong?

解决方案

The problem is the get_deleter free function:

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.

Obviously, the most straightforward implementation of this is to store the typeid of the deleter in the control block. While there are other possible implementations they would (a) be more complicated, (b) lose binary compatibility with RTTI-enabled code, and (c) be against the "spirit" of -fno-rtti.

Another problematic function is dynamic_pointer_cast, which calls dynamic_cast on the stored pointer.

However, the main functionality of shared_ptr is implementable without the use of RTTI features, and indeed as Sergei Nikulov mentions above, the shared_ptr shipped with gcc 4.8.5 works with -fno-rtti, with the exception of the get_deleter and dynamic_pointer_cast functions; as long as you do not use those facilities there is no reason you should not be able to use shared_ptr. This can be contrasted with e.g. any, which is not implementable without the use of typeid.

It is the responsibility of your vendor to provide a standard library that works in all configurations of their compiler, including non-standard ones if they are supporting their use. However, if your vendor is noncooperative you still have a few options:

  • Patch the supplied standard library to remove the broken get_deleter code;
  • Use an alternative standard library (e.g. more recent libstdc++ or libc++);
  • Use an alternative smart pointer facility (e.g. Boost) or write one yourself.

这篇关于没有RTTI的shared_ptr?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆