2009-11-30 9 views
9

Andrei Alexandrescu scrive in Modern C++ Design:Quando typeid può restituire diverse istanze type_info per lo stesso tipo?

Gli oggetti restituiti da typeid avere stoccaggio statico, in modo da non dover preoccuparsi di problemi di vita.

Andrei continua:

Lo standard non garantisce che ogni invocazione di, diciamo, typeid(int) restituisce un riferimento allo stesso type_info oggetto.

Anche se lo standard non lo garantisce, come viene implementato in compilatori comuni, come GCC e Visual Studio?

Supponendo typeid non perde (e restituire una nuova istanza ogni chiamata), è uno "tavolo" per applicazione, per ogni unità di traduzione, per dll/così, o qualcosa di completamente diverso?

Ci sono tempi in cui &typeid(T) != &typeid(T)?

Sono principalmente interessato ai compilatori per Windows, ma qualsiasi informazione per Linux e altre piattaforme è anche apprezzata.

+3

Una ragione importante per questo livello di libertà era effettivamente la preoccupazione per le DLL. – MSalters

risposta

10

Esistono momenti in cui & typeid (T)! = & typeid (T)?

Sono principalmente interessato ai compilatori per Windows, ma qualsiasi informazione per Linux e altre piattaforme è anche apprezzata.

Sì. Sotto Windows DLL non può avere simboli non risolti, quindi. Se si dispone di:

foo.h

struct foo { virtual ~foo() {} }; 

dll.cpp

#include "foo.h" 
... 
foo f; 
cout << &typeid(&f) << endl 

main.cpp

#include "foo.h" 
... 
foo f; 
cout << &typeid(&f) << endl 

darebbe diversi puntatori.Perché prima che dll fosse caricato typeid (foo) dovrebbe esistere sia in dll che exe primario

Più quindi che sotto Linux, se l'eseguibile principale non è stato compilato con -rdynamic (o --export-dynamic) allora typeid sarebbe risolto in simboli diversi nell'eseguibile e in oggetto condiviso (che di solito non accade nelle piattaforme ELF) a causa di alcune ottimizzazioni fatte durante il collegamento dell'eseguibile - rimozione di simboli non necessari.

1

Gli standard a volte lasciano un determinato comportamento non specificato per dare una certa libertà alle implementazioni. In questo caso, il modo in cui i TypeID vengono gestiti viene lasciato all'implementazione del compilatore e viene semplicemente fornito un insieme di regole (in sostanza: non preoccuparti di come viene allocata la memoria per questo).

C'è qualche ragione particolare per cui è necessario essere in grado di confrontare TypeIds in base al loro indirizzo di memoria? TypeIds già sovrascrive == e! = Per fornire la possibilità di confrontarli e fornire un nome() che potrebbe essere utilizzato per identificarli in modo univoco.

Se è disponibile il linguaggio di programmazione C++ (Bjarne Stroustrup), il capitolo 15 contiene molti dettagli sulla gestione delle gerarchie di classi. Forse potresti trovare un'altra soluzione lì?

+3

Hai molti buoni punti, ma questo non risponde alla mia domanda. Non ho bisogno di confrontare gli indirizzi, sono puramente interessato a come viene gestito internamente nei compilatori. Ma i miei interessi principali in questo numero sono quelli del design del compilatore: come e perché è implementato in questo modo. Aggiunta di tag aggiuntivi alla domanda. – dalle

Problemi correlati