Здравствуйте! Я пользуюсь компилятором MinGW GCC и заметил, что появление хотя бы одного виртуального метода в классах сразу даёт +100 Кб к размеру моей программы. Погуглил, и нашёл, что виной всему - т.н. механизм RTTI. А также нашёл опцию, которая этот механизм должна отключать: -fno-rtti. И всё бы ничего, только эта опция не убирает лишний код из программы - все неиспользуемые классы RTTI всё равно остаются прилинкованными мусорным балластом. Для иллюстраци, привожу таблицу виртуальных функций моего тестового класса ('CTestNode2) c включённым RTTI. Видно, что в ней присутствует указатель на typeinfo для класса, а далее следуют специфичные для RTTI таблицы, из-за чего и увеличивается размер приложения... Код | rdata:00414184 public __ZTV10CTestNode2 .rdata:00414184 ; `vtable for'CTestNode2 .rdata:00414184 __ZTV10CTestNode2 dd 0 ; offset to this .rdata:00414188 dd offset __ZTI10CTestNode2 ; `typeinfo for'CTestNode2 .rdata:0041418C off_41418C dd offset __ZN10CTestNode2D1Ev .rdata:0041418C ; DATA XREF: CTestNode2::~CTestNode2()+9↑o .rdata:0041418C ; _main+395↑o .rdata:0041418C ; CTestNode2::~CTestNode2() .rdata:00414190 dd offset __ZN10CTestNode2D0Ev ; CTestNode2::~CTestNode2() .rdata:00414194 dd offset __ZN10CTestNode211TestVMethodEv ; CTestNode2::TestVMethod(void) .rdata:00414198 public __ZTVN10__cxxabiv115__forced_unwindE .rdata:00414198 ; `vtable for'__cxxabiv1::__forced_unwind .rdata:00414198 __ZTVN10__cxxabiv115__forced_unwindE db 0 .rdata:00414199 db 0 .rdata:0041419A db 0 .rdata:0041419B db 0 .rdata:0041419C db 0E8h ; и .rdata:0041419D db 3Eh ; > .rdata:0041419E db 41h ; A .rdata:0041419F db 0 .rdata:004141A0 db 0 .rdata:004141A1 db 0 .rdata:004141A2 db 0 .rdata:004141A3 db 0 .rdata:004141A4 db 0 .rdata:004141A5 db 0 .rdata:004141A6 db 0 .rdata:004141A7 db 0 .rdata:004141A8 db 80h ; Ђ .rdata:004141A9 db 0FAh ; ъ .rdata:004141AA db 40h ; @ .rdata:004141AB db 0 .rdata:004141AC public __ZTVN10__cxxabiv117__class_type_infoE .rdata:004141AC ; `vtable for'__cxxabiv1::__class_type_info .rdata:004141AC __ZTVN10__cxxabiv117__class_type_infoE dd 0 .rdata:004141AC ; DATA XREF: .rdata:`typeinfo for'__cxxabiv1::__forced_unwind↑o .rdata:004141AC ; .rdata:`typeinfo for'__cxxabiv1::__foreign_exception↑o ... .rdata:004141AC ; offset to this .rdata:004141B0 dd offset __ZTIN10__cxxabiv117__class_type_infoE ; `typeinfo for'__cxxabiv1::__class_type_info .rdata:004141B4 off_4141B4 dd offset __ZN10__cxxabiv117__class_type_infoD1Ev .rdata:004141B4 ; DATA XREF: __cxxabiv1::__class_type_info::~__class_type_info()+6↑o .rdata:004141B4 ; __cxxabiv1::__class_type_info::~__class_type_info()↑o ... .rdata:004141B4 ; __cxxabiv1::__class_type_info::~__class_type_info() .rdata:004141B8 dd offset __ZN10__cxxabiv117__class_type_infoD0Ev ; __cxxabiv1::__class_type_info::~__class_type_info() .rdata:004141BC dd offset __ZNKSt9type_info15__is_function_pEv ; std::type_info::__is_function_p(void) .rdata:004141C0 dd offset __ZNKSt9type_info15__is_function_pEv ; std::type_info::__is_function_p(void) .rdata:004141C4 dd offset __ZNK10__cxxabiv117__class_type_info10__do_catchEPKSt9type_infoPPvj ; __cxxabiv1::__class_type_info::__do_catch(std::type_info const*,void **,uint) .rdata:004141C8 dd offset __ZNK10__cxxabiv117__class_type_info11__do_upcastEPKS0_PPv ; __cxxabiv1::__class_type_info::__do_upcast(__cxxabiv1::__class_type_info const*,void **) .rdata:004141CC dd offset __ZNK10__cxxabiv117__class_type_info11__do_upcastEPKS0_PKvRNS0_15__upcast_resultE ; __cxxabiv1::__class_type_info::__do_upcast(__cxxabiv1::__class_type_info const*,void const*,__cxxabiv1::__class_type_info::__upcast_result &) .rdata:004141D0 dd offset __ZNK10__cxxabiv117__class_type_info12__do_dyncastEiNS0_10__sub_kindEPKS0_PKvS3_S5_RNS0_16__dyncast_resultE ; __cxxabiv1::__class_type_info::__do_dyncast(int,__cxxabiv1::__class_type_info::__sub_kind,__cxxabiv1::__class_type_info const*,void const*,__cxxabiv1::__class_type_info const*,void const*,__cxxabiv1::__class_type_info::__dyncast_result &) .rdata:004141D4 dd offset __ZNK10__cxxabiv117__class_type_info20__do_find_public_srcEiPKvPKS0_S2_ ; __cxxabiv1::__class_type_info::__do_find_public_src(int,void const*,__cxxabiv1::__class_type_info const*,void const*) .rdata:004141D8 public __ZTVN10__cxxabiv119__foreign_exceptionE .rdata:004141D8 ; `vtable for'__cxxabiv1::__foreign_exception .rdata:004141D8 __ZTVN10__cxxabiv119__foreign_exceptionE db 0 ----------------------------- И так далее...
|
А вот та же vtable, но уже без RTTI: Код | public __ZTV10CTestNode2 .rdata:004140E4 ; `vtable for'CTestNode2 .rdata:004140E4 __ZTV10CTestNode2 db 0 .rdata:004140E5 db 0 .rdata:004140E6 db 0 .rdata:004140E7 db 0 .rdata:004140E8 db 0 .rdata:004140E9 db 0 .rdata:004140EA db 0 .rdata:004140EB db 0 .rdata:004140EC off_4140EC dd offset __ZN10CTestNode2D1Ev .rdata:004140EC ; DATA XREF: CTestNode2::~CTestNode2()+9↑o .rdata:004140EC ; _main+395↑o .rdata:004140EC ; CTestNode2::~CTestNode2() .rdata:004140F0 dd offset __ZN10CTestNode2D0Ev ; CTestNode2::~CTestNode2() .rdata:004140F4 dd offset __ZN10CTestNode211TestVMethodEv ; CTestNode2::TestVMethod(void) .rdata:004140F8 public __ZTVN10__cxxabiv115__forced_unwindE .rdata:004140F8 ; `vtable for'__cxxabiv1::__forced_unwind .rdata:004140F8 __ZTVN10__cxxabiv115__forced_unwindE db 4 dup(0), 0C4h, 3Eh, 41h, 9 dup(0), 0A0h, 0F0h, 40h .rdata:004140F8 db 0 .rdata:0041410C public __ZTVN10__cxxabiv117__class_type_infoE .rdata:0041410C ; `vtable for'__cxxabiv1::__class_type_info .rdata:0041410C __ZTVN10__cxxabiv117__class_type_infoE dd 0 .rdata:0041410C ; DATA XREF: .rdata:`typeinfo for'__cxxabiv1::__forced_unwind↑o .rdata:0041410C ; .rdata:`typeinfo for'__cxxabiv1::__foreign_exception↑o ... .rdata:0041410C ; offset to this .rdata:00414110 dd offset __ZTIN10__cxxabiv117__class_type_infoE ; `typeinfo for'__cxxabiv1::__class_type_info .rdata:00414114 off_414114 dd offset __ZN10__cxxabiv117__class_type_infoD1Ev .rdata:00414114 ; DATA XREF: __cxxabiv1::__class_type_info::~__class_type_info()+6↑o .rdata:00414114 ; __cxxabiv1::__class_type_info::~__class_type_info()↑o ... .rdata:00414114 ; __cxxabiv1::__class_type_info::~__class_type_info() .rdata:00414118 dd offset __ZN10__cxxabiv117__class_type_infoD0Ev ; __cxxabiv1::__class_type_info::~__class_type_info() .rdata:0041411C dd offset __ZNKSt9type_info15__is_function_pEv ; std::type_info::__is_function_p(void) .rdata:00414120 dd offset __ZNKSt9type_info15__is_function_pEv ; std::type_info::__is_function_p(void) .rdata:00414124 dd offset __ZNK10__cxxabiv117__class_type_info10__do_catchEPKSt9type_infoPPvj ; __cxxabiv1::__class_type_info::__do_catch(std::type_info const*,void **,uint) .rdata:00414128 dd offset __ZNK10__cxxabiv117__class_type_info11__do_upcastEPKS0_PPv ; __cxxabiv1::__class_type_info::__do_upcast(__cxxabiv1::__class_type_info const*,void **) .rdata:0041412C dd offset __ZNK10__cxxabiv117__class_type_info11__do_upcastEPKS0_PKvRNS0_15__upcast_resultE ; __cxxabiv1::__class_type_info::__do_upcast(__cxxabiv1::__class_type_info const*,void const*,__cxxabiv1::__class_type_info::__upcast_result &) .rdata:00414130 dd offset __ZNK10__cxxabiv117__class_type_info12__do_dyncastEiNS0_10__sub_kindEPKS0_PKvS3_S5_RNS0_16__dyncast_resultE ; __cxxabiv1::__class_type_info::__do_dyncast(int,__cxxabiv1::__class_type_info::__sub_kind,__cxxabiv1::__class_type_info const*,void const*,__cxxabiv1::__class_type_info const*,void const*,__cxxabiv1::__class_type_info::__dyncast_result &) .rdata:00414134 dd offset __ZNK10__cxxabiv117__class_type_info20__do_find_public_srcEiPKvPKS0_S2_ ; __cxxabiv1::__class_type_info::__do_find_public_src(int,void const*,__cxxabiv1::__class_type_info const*,void const*) .rdata:00414138 public __ZTVN10__cxxabiv119__foreign_exceptionE .rdata:00414138 ; `vtable for'__cxxabiv1::__foreign_exception .rdata:00414138 __ZTVN10__cxxabiv119__foreign_exceptionE db 0 ----------------------------- И так далее...
|
Видно, что там, где ранее был адрес typeinfo, теперь просто нулевое поле. Однако весь ненужный теперь функционал typeinfo никуда не делся, он по-прежнему в коде! Собственно, ключевой вопрос: как удалить RTTI полностью из кода программы? Спасибо. Это сообщение отредактировал(а) LShadow77 - 10.8.2019, 00:10
|