Когда typeid может возвращать разные экземпляры type_info для одного и того же типа?

StackOverflow https://stackoverflow.com/questions/1819114

Вопрос

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

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

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

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

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

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

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

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

Это было полезно?

Решение

Бывают ли случаи, когда &typeid(T) != &typeid(T)?

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

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

фу.ч

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) из-за некоторых оптимизаций, сделанных при связывании исполняемых файлов - удаление ненужных символов.

Другие советы

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top