2016-07-04 63 views
7

Sto cercando di utilizzare shared_ptr in un progetto incorporato che è stato creato con xc32 1.34 (una derivata di gcc 4.5.2). Il progetto ha disabilitato RTTI con -fno-rtti.shared_ptr senza RTTI?

#include <memory> 

Basta con l'indicazione dell'header mi dà i seguenti errori:

/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 

Quindi quello che voglio sapere è: è generalmente impossibile usare shared_ptr senza RTTI, o sto facendo qualcosa di sbagliato?

+1

C++ senza RTTI non è più C++. Tutte le scommesse (intendo * tutte *) sono disattivate. Chi ti garantisce è possibile utilizzare '' o '' o '' senza RTTI? –

+1

'shared_ptr' type-cancella il deleter che richiede RTTI. Non credo che ci sia un modo per aggirare quello che non è il tuo o trovare un'implementazione che non lo faccia.Sfortunatamente 'boost :: shared_ptr' supporta anche un deleter, forse puoi trovare una versione precedente che non lo fa. – nwp

+3

@nwp RTTI non è richiesto per la cancellazione del tipo. Il solito schema è una classe wrapper di template che implementa una classe astratta. – Quentin

risposta

8

Il problema è la get_deleter funzione libera:

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

Ritorni: Se p possiede un deleter d di tipo cv -unqualified D, restituisce std:addressof(d); altrimenti restituisce nullptr. Il puntatore restituito rimane valido finché esiste un'istanza shared_ptr che possiede d.

Ovviamente, l'implementazione più semplice di questo è per memorizzare il typeid del deleter nel blocco di controllo. Mentre ci sono altre possibili implementazioni, sarebbero (a) più complicate, (b) perdere la compatibilità binaria con il codice abilitato per RTTI, e (c) essere contro lo "spirito" di -fno-rtti.

Un'altra funzione problematica è dynamic_pointer_cast, che chiama dynamic_cast sul puntatore memorizzato.

Tuttavia, la funzionalità principale shared_ptr è realizzabile senza l'impiego di funzionalità RTTI, anzi come Sergei Nikulov cita sopra, i shared_ptr forniti con gcc 4.8.5 opere con -fno-rtti, con l'eccezione delle funzioni get_deleter e dynamic_pointer_cast; finché non utilizzi queste strutture non c'è motivo per cui non dovresti essere in grado di utilizzare shared_ptr. Questo può essere contrastato con per es. any, che non è implementabile senza l'uso di typeid.

È responsabilità del fornitore fornire una libreria standard che funzioni in tutte le configurazioni del compilatore, incluse quelle non standard, se supportano il loro utilizzo. Tuttavia, se il fornitore è non cooperativo avete ancora alcune opzioni:

  • PATCH libreria standard in dotazione per rimuovere il codice rotto get_deleter;
  • Utilizzare una libreria standard alternativa (ad esempio più recente libstdC++ o libC++);
  • Utilizzare una funzione di puntatore intelligente alternativa (ad es. Boost) o scriverne una da soli.