2015-12-18 21 views
13

Il codice C++ può essere compilato con informazioni sul tipo di esecuzione disabilitate, che disabilita dynamic_cast. Tuttavia, i metodi virtuali (polimorfici) devono ancora essere inviati in base al tipo di obiettivo di runtime. Questo non implica che le informazioni sul tipo siano comunque presenti e dynamic_cast dovrebbe essere in grado di funzionare sempre?No RTTI ma metodi ancora virtuali

+1

La mia ipotesi sarebbe che il vtable sia ancora presente ma poiché non contiene alcuna informazione di tipo (solo i puntatori di funzione) le funzioni virtuali continueranno a funzionare. –

+1

Possibile duplicato di http://stackoverflow.com/questions/4486609/when-can-compiling-c-without-rtti-cause-problems ...? –

+0

Per far funzionare dynamic_cast (in casi complessi con ereditarietà multipla) è necessario qualcosa di più delle tabelle di funzioni virtuali – marom

risposta

13

La disattivazione di RTTI uccide dynamic_cast e typeid ma non ha alcun impatto sulle funzioni virtuali. Le funzioni virtuali vengono inviate tramite "vtable" di classi che hanno funzioni virtuali; se vuoi evitare di avere un vtable non puoi semplicemente avere funzioni virtuali.

Un sacco di codice C++ in natura possono lavorare senza dynamic_cast e quasi tutti si può lavorare senza typeid, ma relativamente poche applicazioni C++ sarebbero sopravvissuti senza funzioni virtuali (o, più precisamente, funzioni che dovrebbero essere virtuale diventare non virtuale).

Una tabella virtuale (vtable) è solo un puntatore per istanza a una tabella di ricerca per tipo per tutte le funzioni virtuali. Paghi solo quello che usi (Bjarne adora questa filosofia e inizialmente ha resistito a RTTI). Con RTTI completo, d'altro canto, si finisce con le tue librerie e gli eseguibili che hanno un sacco di stringhe elaborate e altre informazioni utilizzate per descrivere il nome di ciascun tipo e forse altre cose come le relazioni gerarchiche tra i tipi.

Ho visto sistemi di produzione in cui la disattivazione di RTTI ha ridotto del 50% la dimensione degli eseguibili. La maggior parte di questo era dovuta ai nomi di stringa massivi che finiscono in alcuni programmi C++ che usano molto i template.

+0

Ok, quindi 'dynamic_cast' ha bisogno di maggiori informazioni. Ma sembra che 'typeid' possa ancora funzionare, almeno per i tipi che hanno un vtable in ogni caso. È possibile accedere manualmente al puntatore vtable dal codice C++? –

+0

'typeid' non può funzionare perché uno dei suoi scopi principali è quello di fornire un nome per ogni tipo, e quei nomi (le stringhe effettivamente terminate da null) non vengono semplicemente emessi in file oggetto senza RTTI. E no, non è possibile accedere manualmente a Vtable in modo portatile in C++. Ci possono essere modi specifici per la piattaforma, ma anche questo è raro IMO. –

+0

Oh, mi scusi. :) Ho assunto, senza verificare, che 'typeid' restituisce una sorta di numero intero/puntatore obliquo. Ha senso che non funzioni se si tratta di una stringa (edit: in realtà 'class type_info'). –