Terlepas dari kompiler, Anda selalu dapat menghemat saat runtime jika Anda mampu melakukannya
if (typeid(a) == typeid(b)) {
B* ba = static_cast<B*>(&a);
etc;
}
dari pada
B* ba = dynamic_cast<B*>(&a);
if (ba) {
etc;
}
Yang pertama hanya melibatkan satu perbandingan std::type_info
; yang terakhir harus melibatkan melintasi pohon warisan ditambah perbandingan.
Melewati itu ... seperti yang dikatakan semua orang, penggunaan sumber daya adalah implementasi khusus.
Saya setuju dengan komentar orang lain bahwa pengirim harus menghindari RTTI karena alasan desain. Namun, ada yang alasan yang baik untuk menggunakan RTTI (terutama karena meningkatkan :: ada). Itu dalam pikiran, itu berguna untuk mengetahui penggunaan sumber daya yang sebenarnya dalam implementasi umum.
Baru-baru ini saya melakukan banyak penelitian tentang RTTI di GCC.
tl; dr: RTTI di GCC menggunakan ruang yang dapat diabaikan dan typeid(a) == typeid(b)
sangat cepat, di banyak platform (Linux, BSD, dan mungkin platform yang disematkan, tetapi tidak mingw32). Jika Anda tahu Anda akan selalu berada di platform yang diberkati, RTTI sangat dekat dengan gratis.
Detail berpasir:
GCC lebih suka menggunakan ABI "vendor-neutral" C ++ ABI [1], dan selalu menggunakan ABI ini untuk target Linux dan BSD [2]. Untuk platform yang mendukung ABI ini dan juga hubungan lemah, typeid()
mengembalikan objek yang konsisten dan unik untuk setiap jenis, bahkan melintasi batas tautan dinamis. Anda dapat menguji &typeid(a) == &typeid(b)
, atau hanya mengandalkan fakta bahwa tes portabel typeid(a) == typeid(b)
sebenarnya hanya membandingkan pointer secara internal.
Dalam ABI pilihan GCC, kelas vtable selalu memegang pointer ke struktur RTTI per-tipe, meskipun mungkin tidak digunakan. Jadi typeid()
panggilan itu sendiri seharusnya hanya biaya sebanyak pencarian vtable lainnya (sama dengan memanggil fungsi anggota virtual), dan dukungan RTTI tidak boleh menggunakan ruang tambahan untuk setiap objek.
Dari apa yang saya dapat melihat, struktur RTTI yang digunakan oleh GCC (ini semua adalah subkelas std::type_info
) hanya menampung beberapa byte untuk setiap jenis, selain dari namanya. Tidak jelas bagi saya apakah nama-nama itu ada dalam kode keluaran -fno-rtti
. Either way, perubahan ukuran biner yang dikompilasi harus mencerminkan perubahan dalam penggunaan memori runtime.
Eksperimen cepat (menggunakan GCC 4.4.3 pada Ubuntu 10.04 64-bit) menunjukkan bahwa -fno-rtti
sebenarnya meningkatkan ukuran biner dari program pengujian sederhana beberapa ratus byte. Ini terjadi secara konsisten di kombinasi -g
dan -O3
. Saya tidak yakin mengapa ukurannya akan meningkat; satu kemungkinan adalah bahwa kode STL GCC berperilaku berbeda tanpa RTTI (karena pengecualian tidak akan berfungsi).
[1] Dikenal sebagai Itanium C ++ ABI, yang didokumentasikan di http://www.codesourcery.com/public/cxx-abi/abi.html . Nama-nama itu sangat membingungkan: namanya mengacu pada arsitektur pengembangan asli, meskipun spesifikasi ABI bekerja pada banyak arsitektur termasuk i686 / x86_64. Komentar dalam sumber internal GCC dan kode STL menyebut Itanium sebagai ABI "baru" berbeda dengan "lama" yang mereka gunakan sebelumnya. Lebih buruk lagi, ABI "baru" / Itanium merujuk ke semua versi yang tersedia melalui -fabi-version
; ABI "lama" mendahului versi ini. GCC mengadopsi ABI Itanium / versi / "baru" dalam versi 3.0; ABI "lama" digunakan pada 2.95 dan sebelumnya, jika saya membaca changelog mereka dengan benar.
[2] Saya tidak bisa menemukan std::type_info
stabilitas daftar sumber daya objek berdasarkan platform. Untuk kompiler saya memiliki akses ke, saya menggunakan berikut: echo "#include <typeinfo>" | gcc -E -dM -x c++ -c - | grep GXX_MERGED_TYPEINFO_NAMES
. Makro ini mengontrol perilaku operator==
untuk std::type_info
dalam STL GCC, mulai dari GCC 3.0. Saya memang menemukan bahwa mingw32-gcc mematuhi Windows C ++ ABI, di mana std::type_info
objek tidak unik untuk jenis di seluruh DLL; typeid(a) == typeid(b)
panggilan di strcmp
bawah penutup. Saya berspekulasi bahwa pada target tertanam program tunggal seperti AVR, di mana tidak ada kode untuk ditautkan, std::type_info
objek selalu stabil.