LINUX.ORG.RU

Сопоставление std::type_index из разных библиотек.

 


0

2

Есть две библиотеки, в одной определён полиморфный тип Тип1, в другой определён полиморфный тип Тип2. Каждая из библиотек выдаёт наружу std::type_index от своего Типа. Дальше обе библиотеки компонуются с исполняемым модулем, а в исполняемом модуле берутся эти std::type_indexы и сравниваются.

Вопрос, существует ли гарантия, что std::type_indexы из разных библиотек находятся в одном «адресном пространстве»? Т.е., если Тип1 и Тип2 это один и тот же тип, то эти std::type_indexы из разных библиотек будут равны, а если Тип1 и Тип2 это разные типы, то std::type_indexы покажут отрицательный ответ при сравнении на равенство. Даётся ли такая гарантия стандартом?

★★★

Последнее исправление: normann (всего исправлений: 1)

Если классы являются потомками общего надкласса, реализующего этот интерфейс, то да. Иначе — нет, и тогда они либо не должны использоваться в одном проекте, либо должны быть описаны в разных пространствах имён, потому что это разные типы, разные интерфейсы и разные индексы.

в одном «адресном пространстве»?

В одном пространстве имён это называется. И реализующие общий интерфейс, являясь потомками одного предка. А адресное пространство в программе всегда одно.

aureliano15 ★★
()
Ответ на: комментарий от aureliano15

Некомпетентный бред, ты даже не понял вопроса. Какие интерфейсы, какие потомки, какие пространства имен, что ты несешь?

Siborgium ★★★★★
()
Последнее исправление: Siborgium (всего исправлений: 1)
Ответ на: комментарий от aureliano15

Если ты считаешь, что понял вопрос, то ответь на него, а не неси бред.

Поддерживаю, оскорблять незачем.

Если классы являются потомками...

Что-то не так с этим. У меня получается такая штука, Тип1 и Тип2 у меня не полиморфные, возвращают изнутри своих библиотек значения std::type_info::hash_code() и свои std::type_indexы, те же коды и индексы по этим типам вычисляются в исполняемом модуле и сравниваются с теми что вернули типы из библиотек, и обнаруживается абсолютное равенство, коды идентичны и сравнение на равенство индексов возвращает положительный результат. Кроме того, в каждой из библиотек объявлен внутренний класс, один в один одинаковый в обоих библиотеках, из библиотек возвращается коди и индексы этих классов и сравниваются, и так же обнаруживается абсолютная идентичность. Если в одном из внутренних классов что-нибудь поменять, например имя, то показатели уже равными не будут. Собирал на линуксе с gcc и на винде с mingw и со студийным компилятором. Результат одинаковый на всех платформах.

normann ★★★
() автор топика
Последнее исправление: normann (всего исправлений: 1)
Ответ на: комментарий от normann

Так то он одинаковый, но как упомянули уже здесь и на stackoverflow, нет никаких гарантий и лучше не уповать на это. Потому что удача может распорядиться так, что в один очень ответственный момент ты возьмешь, да и словишь ошибку из-за того, что положился на все это.

А можно подробнее, что там за архитектура у тебя, может можно переделать все так, чтобы не нужно было задействовать весь этот механизм?

rumgot ★★★★★
()
Последнее исправление: rumgot (всего исправлений: 2)

В gcc зависит от того, как собирается type_info.name() - mangled-строка, почти как у названий функций/методов. А собирается в соответствии c++abi, который не стандартизирован. В пределах одного c++abi (скорее всего) будет работать корректно.

anonymous
()
Ответ на: комментарий от normann

Тип1 и Тип2 у меня не полиморфные, возвращают изнутри своих библиотек значения std::type_info::hash_code() и свои std::type_indexы

Теперь, кажется, понял. Сначала действительно невнимательно прочитал и решил, что речь о полиморфизме.

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

А если имя внутреннего класса не трогать, а содержимое изменить?

Например:

test_ab.cxx:

#include <iostream>

class A
{
  public:
   int x, y, z;
};

class B
{
  public:
   B();
};

B::B() {
  A a;
  std::cout << "Hello from B: " << typeid(A).name() << ", " << typeid(A).hash_code() << std::endl;
}

test_ac.cxx:

#include <iostream>

class A
{
  public:
   int x, y;
};

class C
{
  public:
   C();
};

C::C() {
  A a;
  std::cout << "Hello from C: " << typeid(A).name() << ", " << typeid(A).hash_code() << std::endl;
}

test_bc.cxx:

class B
{
  public:
   B();
};

class C
{
  public:
   C();
};

int main()
{
  B b;
  C c;

  return 0;
}

В модулях test_ab.cxx и test_ac.cxx я определил два разных внутренних класса A, имеющих одинаковое имя, но разные размеры (1-й содержит 3 поля x, y и z, а 2-й — только 2 — x и y). В модуле test_bc.cxx объявляются классы B и C, каждый из которых содержит переменную класса A из соответствующего модуля (т. е. эти переменные разных типов и размеров, хотя названия типов одинаковые) и определяется функция main, из которой вызываются конструкторы классов B и C, которые, в свою очередь, выводят внутреннее имя и хэш-код каждого из классов A. Теперь компилируем всё это и запускаем:

~$ g++ -o test_bc test_ab.cxx test_ac.cxx test_bc.cxx
~$ ./test_bc
Hello from B: 1A, 1295143305205299629
Hello from C: 1A, 1295143305205299629

Как видно, и имена, и хэши обоих типов A одинаковы, хотя это разные типы не только формально, но и по сути, т. к. имеют разное число полей.

Поэтому мой ответ (если я, конечно, на этот раз понял правильно суть проблемы): на индексы с хэшами в данном случае полагаться не стоит, т. к. для разных типов с одинаковыми названиями они могут дать одинаковые значения. Ну и ещё хэши иногда могут быть одинаковыми для разных названий в случае коллизии. Это маловероятно, но тоже полностью исключать такой возможности я бы не стал.

aureliano15 ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.