Когда typeid может вернуть разные экземпляры type_info для одного и того же типа? - PullRequest
10 голосов
/ 30 ноября 2009

Андрей Александреску пишет в Современный дизайн C ++ :

Объекты, возвращаемые typeid, имеют статическое хранилище, поэтому вам не нужно беспокоиться о проблемах на всю жизнь.

Андрей продолжает:

Стандарт не гарантирует, что каждый вызов, скажем, typeid(int) возвращает ссылку на то же самое type_info объект.

Несмотря на то, что стандарт не гарантирует этого, как это реализовано в распространенных компиляторах, таких как GCC и Visual Studio?

Предполагая, что typeid не дает утечки (и возвращает новый экземпляр при каждом вызове), это одна таблица на приложение, на единицу перевода, на dll / so или что-то совершенно другое?

Бывают ли времена, когда &typeid(T) != &typeid(T)?

В основном меня интересуют компиляторы для Windows, но любая информация для Linux и других платформ также приветствуется.

Ответы [ 2 ]

10 голосов
/ 28 декабря 2009

Есть ли случаи, когда & typeid (T)! = & Typeid (T)?

В основном меня интересуют компиляторы для Windows, но любая информация для Linux и других платформ также приветствуется.

Да. Под Windows DLL не может иметь неразрешенных символов, таким образом. Если у вас есть:

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

Даст вам разные указатели. Потому что до загрузки dll должен существовать typeid (foo) как в dll, так и в первичном exe

Более того, в Linux, если основной исполняемый файл не был скомпилирован с -rdynamic (или --export-dynamic), тогда typeid будет разрешен в разных символах исполняемого файла в разделяемом объекте (что обычно не происходит на платформах ELF) из-за некоторых оптимизаций, выполняемых при компоновке исполняемого файла - удаление ненужных символов.

1 голос
/ 30 ноября 2009

Стандарты иногда оставляют определенное поведение неопределенным, чтобы дать реализациям некоторую свободу. В этом случае то, как управляются TypeID, оставлено на усмотрение реализации компилятора, и вам просто дают набор правил (по сути: не беспокойтесь о том, как выделяется память для этого).

Есть ли какая-то конкретная причина, по которой вам нужно иметь возможность сравнивать TypeIds на основе их адреса памяти? TypeIds уже переопределяют == и! =, Чтобы предоставить вам возможность сравнивать их и предоставлять имя (), которое может использоваться для их уникальной идентификации.

Если у вас есть язык программирования C ++ (Bjarne Stroustrup), глава 15 содержит много подробностей о работе с иерархиями классов. Может быть, вы могли бы найти другое решение там?

...