¿En Cuándo usar C sobre C ++ y C ++ sobre C? hay una declaración wrt. para codificar excepciones de tamaño / C ++:
Jerry responde (entre otros puntos):
(...) tiende a ser más difícil producir ejecutables realmente pequeños con C ++. Para sistemas realmente pequeños, rara vez escribes mucho código de todos modos, y el extra (...)
a lo que pregunté por qué sería eso, a lo que Jerry respondió:
Lo principal es que C ++ incluye manejo de excepciones, que (al menos generalmente) agrega un mínimo al tamaño ejecutable. La mayoría de los compiladores le permitirán deshabilitar el manejo de excepciones, pero cuando lo haga, el resultado ya no será C ++. (...)
que realmente no dudo a nivel técnico del mundo real.
Por lo tanto, estoy interesado (por pura curiosidad) en escuchar ejemplos del mundo real en los que un proyecto eligió C ++ como lenguaje y luego eligió desactivar las excepciones. (No solo las excepciones de "no usar" en el código de usuario, sino deshabilitarlas en el compilador, para que no pueda lanzar o atrapar excepciones). ¿Por qué un proyecto elige hacerlo? (Todavía usando C ++ y no C, pero excepciones): ¿cuáles son / fueron los motivos (técnicos)?
Anexo: Para aquellos que deseen elaborar sus respuestas, sería bueno detallar cómo se manejan las implicaciones de las no excepciones:
- Las colecciones STL (
vector
, ...) no funcionan correctamente (no se puede informar la falla de asignación) new
no puede tirar- Los constructores no pueden fallar
fuente
Respuestas:
Casi todos los juegos de consola están en C ++ con la excepción desactivada, incluso hoy. De hecho, es la configuración predeterminada para los compiladores de C ++ destinados a esas consolas. A veces, no se garantiza que algunas funciones de C ++ funcionen correctamente en esos compiladores, como la herencia múltiple (por ejemplo, estoy pensando en un compilador predeterminado de consola muy conocido).
Además, otro ejemplo es el SDK de hardware Arduino que usa gcc sin excepción activada en C ++, y otras cosas como que no se proporciona STL .
Hay algunas razones técnicas, buenas o malas, lo que sea, no es mi consejo, sino razones que he escuchado:
Creo que las excepciones pueden ser útiles incluso en los juegos, pero eso es cierto que en los juegos de consola no es realmente útil.
Actualizar:
Estoy agregando otro ejemplo sorprendente aquí: LLVM / CLang no usa excepción ni RTTI por las siguientes razones :
CLang es bien conocido por su velocidad de compilación y errores explícitos, pero también es un compilador único que tiene un código realmente fácil de seguir.
fuente
Jerry dijo: ... el resultado ya no es C ++ , mientras que mi metáfora es que es claramente C ++, solo un dialecto ligeramente diferente porque los programas utilizan otras formas, convenciones y estilos escritos.
Aquí están mis razones principales para deshabilitarlas:
Compatibilidad binaria
Cruzar los límites del idioma y la traducción no está universalmente bien definido o indefinido. Si desea garantizar que su programa funcione dentro del dominio de comportamiento definido, deberá poner en cuarentena las excepciones en los puntos de salida del módulo.
Tamaño ejecutable
Aquí están los tamaños binarios de un programa libre de excepciones que escribí, creado sin y con excepciones habilitadas:
Sin excepciones:
Con excepciones:
Recordatorio: es una colección de bibliotecas y programas que contienen cero lanzamientos / capturas. La bandera compilador hace permitir excepciones en la biblioteca estándar de C ++. Por lo tanto, el costo en el mundo real es más del 19% visto en este ejemplo.
Compilador: apple gcc4.2 + llvm. Tamaños en MB.
Velocidad
A pesar del término "excepciones de costo cero", todavía agregan algunos gastos generales incluso cuando nada arroja. En el caso anterior, es un programa crítico de rendimiento (procesamiento de señales, generación, presentación, conversiones, con grandes conjuntos de datos / señales, etc.). Las excepciones no son una característica necesaria en este diseño, mientras que el rendimiento es muy importante.
Corrección del programa
Parece una razón extraña ... Si lanzar no es una opción, debe escribir programas relativamente estrictos, correctos y bien probados para garantizar que su programa se ejecute correctamente, y que los clientes usen las interfaces correctamente (si me da un mal argumento o no lo hace) No verifique un código de error, entonces se merece UB). ¿El resultado? La calidad de la implementación mejora enormemente y los problemas se solucionan rápidamente.
Sencillez
Las implementaciones de manejo de excepciones a menudo no se mantienen actualizadas. También agregan mucha complejidad porque una implementación puede tener muchas, muchas, muchas secuencias de salida. Es más sencillo leer y mantener programas altamente complejos cuando utilizan un pequeño conjunto de estrategias de salida bien definidas, tipadas, que surgen y son manejadas por el cliente. En otros casos, las implementaciones pueden con el tiempo implementar más lanzamientos o sus dependencias pueden introducirlos. Los clientes no pueden defenderse fácil o adecuadamente contra todas estas salidas. Escribo y actualizo muchas bibliotecas, hay una evolución y una mejora frecuentes. Intentar mantener todo sincronizado con las secuencias de salida de excepción (en una base de código grande) no sería un buen uso del tiempo y probablemente agregaría mucho ruido y ruido. Debido a la mayor corrección del programa y más pruebas,
Historia / Código existente
En algunos casos, nunca se introdujeron por razones históricas. Una base de código existente no los usaba, cambiar los programas podría llevar muchos años y hacer que sea realmente feo de mantener debido a la superposición de convenciones e implementaciones.
Desventajas
Por supuesto, hay inconvenientes, los más importantes son: incompatibilidad (incluido binario) con otras bibliotecas, y el hecho de que tendrá que implementar una buena cantidad de programas para adaptarse a este modelo.
fuente
malloc
devoluciones0
), el asignador ingresa a unowhile (1)
que tiene un cambio de contexto, seguido de otro intento de asignación. En esta base de código, solía ser que nuevo a través del asignador podría devolver 0, pero la implementación más reciente ha estado funcionando bien. (cont)Google no aprueba las excepciones en su Guía de estilo de C ++ , principalmente por razones históricas:
(Énfasis del editor)
fuente
Qt casi nunca usa excepciones. Los errores en Qt se indican con códigos y señales de error. La razón declarada oficialmente es:
Hoy, una crítica común de Qt es que su seguridad de excepción no está completa.
fuente
Symbian C ++ (usado en algunos teléfonos móviles Nokia) no usa excepciones, al menos no directamente, porque los compiladores de C ++ no las implementaron de manera confiable cuando Symbian se desarrolló por primera vez.
fuente
Yo / nunca / uso excepciones. Hay varias razones para esto, pero las dos razones principales son que nunca las he necesitado para producir código robusto y que reducen el rendimiento en tiempo de ejecución.
He trabajado en el código de producción que usa y deshabilita las excepciones: el código que permitía las excepciones era uniformemente peor. En algunos lugares, se utilizaron excepciones para el control de flujo genuino en lugar del manejo de errores, que es muy pesado, anti-rendimiento y difícil de depurar. En general, los problemas de depuración en el código lleno de excepciones fueron más difíciles que en el código libre de excepciones, en parte debido a la pila y las dificultades intrínsecas del mecanismo de excepción, pero mucho más que eso fue debido al código perezoso que se fomentó como resultado de tener disponible un manejo de excepciones.
No hay nada realmente malo con las excepciones en sí mismas / si no le importa el rendimiento / y no tiene tiempo para hacer algo correctamente: son una característica del lenguaje para el manejo de errores y un buen sustituto para un mecanismo adecuado de manejo de errores. Sin embargo, casi siempre hay / mejores / formas de manejar los errores, como con su propia lógica (es difícil de explicar, es casi de sentido común). Si no es su error, pero proviene de una biblioteca (por ejemplo, la biblioteca estándar), entonces debe respetar la elección de excepciones o tener algún bloqueo, pero siempre cuestionaría esa elección. Nunca he visto una situación en la que las excepciones fueran realmente la mejor solución.
Las afirmaciones son más depurables, los códigos de error son menos pesados ... entre los dos, si se usan correctamente, es más fácil leer, depurar y mantener el código, que es más rápido. Sus victorias en todo ...
fuente
En el estándar de codificación Joint Strike Fighter C ++ de Bjarne et. al., las excepciones están prohibidas debido a los duros requisitos en tiempo real de los aviones de combate.
Citado de las preguntas frecuentes de C ++ de Bjarne .
Recuerde, C ++ probablemente ejecuta la más amplia variedad de software de todos los lenguajes ...
fuente
Es algo importante en el diseño de la biblioteca C ++. Muchas veces con una interfaz C es un poco desagradable lanzar una excepción de su biblioteca de terceros al cliente. Señale que si su biblioteca arroja, está eliminando un conjunto de clientes que lo habrían usado, dado que tenía una garantía de no tirar (por cualquier razón que el cliente tenga como restricción de excepciones).
Personalmente, he visto que se abusan de las excepciones cuando se le dice al equipo que "agregue una excepción" cuando sucede algo no tan terrible. Por supuesto, verá el error aquí: la excepción se arrojó en el código antes de que alguien descubriera qué hacer con él. Ese proyecto tuvo algunos accidentes, ya que estos lanzamientos profundos se formaban ocasionalmente.
fuente
Quizás a este respecto, vale la pena mencionar Embedded C ++ . Embedded C ++ es una variante de C ++ diseñada (obviamente suficiente) para sistemas embebidos. Básicamente es un subconjunto adecuado de C ++, con (entre otras cosas) plantillas, espacios de nombres y manejo de excepciones eliminado.
Debo agregar que si bien EC ++ causó un pequeño revuelo cuando era nuevo, parece que en su mayoría se han quedado bastante silenciosos. No estoy seguro de si las personas han perdido interés, o si su primer intento fue simplemente tan perfecto que nadie ha visto ninguna razón para meterse con eso durante una década más o menos.
<closed captioning for the humor impaired>Yeah, right!</closed captioning>
fuente
Un buen ejemplo es la programación en modo kernel.
Puede usar C ++ allí para obtener un código más limpio, pero sin excepciones. No hay una biblioteca de tiempo de ejecución para ellos y el manejo de excepciones utiliza demasiada memoria de pila que es muy limitada en el núcleo (Experimenté con excepciones de C ++ en el núcleo de Windows NT y el lanzamiento y desenrollamiento de excepciones consume la mitad de la pila disponible, muy fácil de obtener desbordamiento de pila y bloquear todo el sistema).
Por lo general, define sus propios
new
ydelete
operadores. Tambiénplacement new
encontré referencias de valor de a y c ++ 11 bastante útiles . No se pueden utilizar STL u otras bibliotecas de modo de usuario de C ++ que se basan en excepciones.fuente
Cuando intenta mantener baja la memoria ejecutable. Normalmente se realiza en sistemas integrados (o móviles). Para las aplicaciones de escritorio nunca es necesario, sin embargo, en los servidores, se puede considerar si desea la mayor cantidad de memoria RAM posible para el servidor web o para sql.
fuente