Почему я могу поймать объект или dynamic_cast, даже если его объект std :: type_info отличается?

Я проводил эксперимент и определил один и тот же класс как в программе, так и в совместно используемой библиотеке, которую я выбрал из программы, и убедился, что в ее таблице dynsym нет программы для объекта типа info. Затем я выбрасываю объект этого класса из общей библиотеки и пытаюсь поймать его, используя тот же тип класса.

Я ожидал, что реализация в linux и gcc не поймает исключение, потому что объекты типа info обоих классов в программе и в разделяемой библиотеке различаются, и поэтому совпадение будет возможно только в том случае, если среда выполнения выполнит сравнение строк из искаженного класса. имена.

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

редактировать

Исходя из того, что утверждает Itanium ABI, наблюдаемое поведение может показаться несоответствующим. Что мне здесь не хватает?

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

Поскольку два typeinfo имеют разные адреса, описанные структуры, следовательно, представляют разные типы. Поэтому приведение не должно было произойти, и исключение не должно было быть поймано.

2

Решение

определил один и тот же класс как в программе, так и в общей библиотеке, которую я добавляю из программы — Поздравляем с нарушением Единого правила определения. Вы должны знать, что в стране неопределенного поведения может произойти все что угодно.

0

Другие решения

Itanium ABI явно заявляет, что сравнивать объекты type_info для классов искаженное имя, которая действительно является предполагаемой реализацией в вашем вопросе.

https://refspecs.linuxbase.org/cxxabi-1.86.html#rtti

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

дескрипторы typeinfo также имеют неопределенную связь, что прекрасно. Однако используемое определение требует, чтобы они были помещены в группы COMDAT. Группы COMDAT должны быть дедуплицированы компоновщиком, по крайней мере, как часть статической компоновки. В настоящее время я не могу определить, требуется ли их дедупликация для динамического связывания, но это кажется логичным.

Итак, в итоге, ответ на ваш вопрос: «Он обработан, потому что авторы ABI предвидели эту ситуацию и гарантировали, что она была обработана».

0

По вопросам рекламы [email protected]