example - typeinfo c++
¿Cuál es el propósito real de std:: type_info:: name()? (2)
¿Hay casos reales de uso a nivel de código de producción para
std::type_info::name()
no sea el registro?
El ABI de Itanium describes cómo el operator==
para los objetos std::type_info
se puede implementar fácilmente en términos de cadenas de prueba devueltas desde std::type_info::name()
para la igualdad de punteros.
En un espacio de direcciones no plano, donde podría ser posible tener múltiples objetos type_info
para el mismo tipo (por ejemplo, debido a que una biblioteca dinámica se ha cargado con RTLD_LOCAL
), la implementación de operator==
podría necesitar usar strcmp
para determinar si hay dos tipos son lo mismo.
Por lo tanto, la función name()
se utiliza para determinar si dos objetos type_info
se refieren al mismo tipo. Para ejemplos de casos de uso reales, esto se usa normalmente en al menos dos lugares en la biblioteca estándar, en std::function<F>::target<T>()
y std::get_deleter<D>(const std::shared_ptr<T>&)
.
Si no está usando RTTI, entonces todo eso es irrelevante, ya que de todos modos no tendrá ningún objeto type_info
(y, por lo tanto, en libstdc ++ no se pueden usar las function::target
y get_deleter
).
Creo que el código de manejo de excepciones de GCC usa las direcciones de los objetos type_info
, no las direcciones de las cadenas devueltas por name()
, por lo que si usa excepciones pero no RTTI, no se necesitan las cadenas name()
.
Hoy, un colega mío vino y me hizo la pregunta como se menciona en el título.
Actualmente está intentando reducir la huella de los binarios de una base de código, que también se usa en objetivos pequeños (como Cortex M3 y similares). Al parecer, han decidido compilar con RTTI activado (GCC en realidad), para admitir el manejo adecuado de excepciones.
Bueno, su queja principal fue por qué std::type_info::name()
es realmente necesario para el soporte de RTTI, y me preguntaron, si conozco una manera de simplemente suprimir la generación de los literales de cadenas necesarios para respaldar esto, o al menos para acortarlos
std :: type_info :: name
const char* name() const;
Devuelve una cadena de caracteres terminada en nulo definida por la implementación que contiene el nombre del tipo. No se dan garantías, en particular, la cadena devuelta puede ser idéntica para varios tipos y cambiar entre invocaciones del mismo programa.
Un, aunque sea un compilador específico, la implementación de, por ejemplo, el operador dynamic_cast<>
no usaría esta información, sino algo como una etiqueta hash para la determinación de tipo (similar para catch()
bloques catch()
con manejo de excepciones).
Creo que lo último se expresa claramente en las definiciones estándar actuales para
Tuve que estar de acuerdo en que tampoco veo el punto de usar std::type_info::name()
, que no sea para fines de depuración (registro). No estaba 100% seguro de que el manejo de excepciones funcionará solo sin RTTI con las versiones actuales de GCC (creo que están usando 4.9.1), así que dudé en recomendar simplemente desactivar RTTI.
También es el caso de que dynamic_casts<>
se usan en su base de código, pero para estos, simplemente recomendé no usarlo, en favor de static_cast
(en realidad no tienen algo como complementos, o necesitan una detección de tipo de tiempo de ejecución que no sea afirmaciones).
Pregunta:
- ¿Hay casos reales de uso a nivel de código de producción para
std::type_info::name()
no sea el registro?
Subpreguntas (más concretas):
¿Alguien tiene una idea, cómo superar (evitar) la generación de estos literales de cadena inútiles (bajo el supuesto de que nunca se usarán)?
¿RTTI es realmente necesario para soportar el manejo de excepciones con GCC?
(Esta parte está bien resuelta ahora por la respuesta de @ Sehe , y la he aceptado. La otrastd::type_info
aún permanece para las instanciasstd::type_info
generadasstd::type_info
para cualquier excepción usada en el código. Estamos bastante seguros de que estos literales nunca se usan en ningún lado)
Bit de relacionado: elimine las funciones de tiempo de ejecución no utilizadas que hacen que el ejecutable (GCC)
Aislando este bit:
- El punto es, si apagan RTTI, ¿el manejo de excepciones seguirá funcionando correctamente en GCC? - Hace más de 1 hora
La answer es sí:
-fno-rtti
Deshabilite la generación de información sobre cada clase con funciones virtuales para uso de las funciones de identificación de tipo de tiempo de ejecución de C ++ (
dynamic_cast
ytypeid
). Si no usa esas partes del idioma, puede ahorrar algo de espacio usando esta bandera. Tenga en cuenta que el manejo de excepciones utiliza la misma información, pero la generará según sea necesario . El operadordynamic_cast
todavía se puede utilizar para conversiones que no requieren información de tipo de tiempo de ejecución, es decir, conversiones paravoid *
o para clases base no ambiguas.