Quando pode typeid retorno diferente type_info instâncias de mesmo tipo?
-
10-07-2019 - |
Pergunta
Andrei Alexandrescu em Modern C ++ projeto :
Os objetos retornados por
typeid
têm armazenamento estático, para que você não tem que se preocupar com questões da vida.
Andrei continua:
A norma não garante que cada invocação de, digamos,
typeid(int)
devolve uma referência para a mesmatype_info
objeto.
Mesmo que a norma não garantir isso, como isso é implementado em compiladores comuns, tais como GCC e Visual Studio?
Assumindo typeid
não vaza (e retornar uma nova instância de cada chamada), é uma "mesa" por aplicativo, por unidade de tradução, por dll / so, ou algo completamente diferente?
Existem momentos em que &typeid(T) != &typeid(T)
?
Estou interessado principalmente em compiladores para Windows, mas nenhuma informação para Linux e outras plataformas também é apreciado.
Solução
Existem momentos em que & typeid (T)! = & Typeid (T)?
Estou interessado principalmente em compiladores para Windows, mas nenhuma informação para Linux e outras plataformas também é apreciado.
Sim. Sob Windows DLL não podem ter símbolos não resolvidos, assim. Se você tem:
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
iria dar-lhe ponteiros diferentes. Porque antes dll foi carregado typeid (foo) deve existir em ambos os dll e exe principal
Mais de que, sob o Linux, se executável principal não foi compilado com -rdynamic (ou --export-dinâmica), então typeid seria resolvido com símbolos diferentes no executável e no objeto compartilhado (o que geralmente não acontece em plataformas ELF) por causa de algumas otimizações feitas ao ligar executável -. remoção de símbolos desnecessários
Outras dicas
Padrões às vezes deixam determinado comportamento não especificado, a fim de dar implementações alguma liberdade. Neste caso, como TypeIDs são geridas está sendo deixada para a implementação do compilador e você está simplesmente sendo dado um conjunto de regras (essencialmente: Não se preocupe com a forma como memória para isso está sendo alocado)
.Existe alguma razão específica para que você precisa ser capaz de comparar TypeIds com base em seu endereço de memória? TypeIds já substituir == e! =, A fim de fornecê-lo com a capacidade de compará-los, e fornecer um nome () que pode ser usado para identificá-los de forma exclusiva.
Se você tem o C ++ Programming Language (Bjarne Stroustrup) disponíveis, capítulo 15 tem um monte de detalhes sobre como manusear hierarquias de classe. Talvez você pode encontrar outra solução lá?