La seguridad ante excepciones es el estado en el que el código funciona correctamente cuando se producen excepciones. [ 1 ] Para ayudar a garantizar la seguridad ante excepciones, los desarrolladores de la biblioteca estándar de C++ han ideado un conjunto de niveles de seguridad ante excepciones , garantías contractuales del comportamiento de las operaciones de una estructura de datos con respecto a las excepciones. Los implementadores de la biblioteca y los clientes pueden utilizar estas garantías al razonar sobre la corrección del manejo de excepciones . Los niveles de seguridad ante excepciones se aplican igualmente a otros lenguajes y mecanismos de manejo de errores. [ 2 ]
Historia
Como escribe David Abrahams , «nadie hablaba de "seguridad ante errores" antes de que C++ tuviera excepciones». [ 3 ] El término apareció como tema de publicaciones en JTC1/SC22/WG21 , el comité de estándares de C++, ya en 1994. [ 4 ] Abrahams formalizó por primera vez la seguridad ante excepciones para la biblioteca estándar de C++ en STLport , estableciendo la distinción entre seguridad básica y seguridad fuerte. [ 5 ] Esto se extendió a las garantías modernas de seguridad básica, fuerte y sin excepciones en una propuesta posterior. [ 6 ]
Fondo
Las excepciones proporcionan una forma de flujo de control no local , ya que una excepción puede "propagarse" desde una función llamada. Esta propagación puede causar un error de seguridad de excepciones al romper invariantes de una estructura de datos mutable, como sigue: [ 7 ]
- Un paso de una operación sobre una estructura de datos mutable modifica los datos y rompe una invariante.
- Se lanza una excepción y el control "se propaga hacia arriba", omitiendo el resto del código de la operación que restauraría la invariante.
- La excepción se captura y se recupera, o
finallyse entra en un bloque. - La estructura de datos con el invariante roto es utilizada por el código que asume el invariante, lo que resulta en un error.
Se puede decir que un código con un error como el anterior es "inseguro ante excepciones". [ 7 ]
Clasificación
La biblioteca estándar de C++ proporciona varios niveles de seguridad ante excepciones (en orden decreciente de seguridad): [ 8 ]
- Garantía de no fallos , también conocida como transparencia ante fallos : Se garantiza que las operaciones tendrán éxito y cumplirán con todos los requisitos incluso en situaciones excepcionales. Si se produce una excepción, se gestionará internamente y no será visible para los clientes.
- Seguridad fuerte ante excepciones , también conocida como semántica de confirmación o reversión : las operaciones pueden fallar, pero se garantiza que las operaciones fallidas no tendrán efectos secundarios, dejando los valores originales intactos. [ 9 ]
- Seguridad básica ante excepciones : La ejecución parcial de operaciones fallidas puede generar efectos secundarios, pero se conservan todas las invariantes . Los datos almacenados contendrán valores válidos que pueden diferir de los originales. Las fugas de recursos (incluidas las de memoria ) suelen descartarse mediante una invariante que establece que todos los recursos se contabilizan y gestionan.
- Seguridad sin excepciones : No se ofrecen garantías.
Por lo general, se requiere al menos seguridad básica contra excepciones para escribir código robusto. A veces, lograr niveles de seguridad más altos puede ser difícil y podría generar una sobrecarga debido a copias adicionales. Un mecanismo clave para la seguridad contra excepciones es una finallycláusula, o una sintaxis similar de manejo de excepciones , que asegura que cierto código se ejecute siempre cuando se sale de un bloque, incluso por excepciones. Varios lenguajes tienen construcciones que simplifican esto, en particular usando el patrón dispose , llamado using, with, o try-with-resources.
Ejemplo
Consideremos un tipo de vector inteligente, como el de C++ o Java . Cuando se agrega un elemento a un vector , este debe agregarlo a la lista interna de objetos y actualizar un campo de conteo que indica cuántos objetos contiene . También puede ser necesario asignar nueva memoria si la capacidad existente no es suficiente.std::vectorArrayListxvxv
Alternativas de seguridad excepcionales:
- Garantía de no lanzamiento
- Se implementa garantizando que la asignación de memoria nunca falle, o definiendo
insertel comportamiento de la función en caso de fallo de asignación (por ejemplo, haciendo que la función devuelva un resultado booleano que indique si la inserción se realizó correctamente). - Seguridad de excepción fuerte
- Se implementa realizando primero la asignación necesaria y, si no se producen errores, intercambiando los búferes (el método de copia e intercambio ). En este caso, la inserción
xsevrealiza correctamente o elvbúfer permanece sin cambios a pesar del fallo de asignación. - Seguridad de excepciones básicas
- Se implementa asegurando que el campo de conteo refleje el tamaño final de
v. Por ejemplo, si se encuentra un error, lainsertfunción podría liberar completamente la memoriavy restablecer su campo de conteo a cero. En caso de fallo, no se pierden recursos, perovel valor anterior de no se conserva. - Seguridad sin excepciones
- Un fallo de inserción podría provocar contenido corrupto
v, un valor incorrecto en el campo de recuento o una fuga de recursos .
Referencias
- ↑ Crichton, Alex (24 de julio de 2015). "Rust RFC: Estabilizar catch_panic" . El lenguaje de programación Rust . Consultado el 26 de mayo de 2022.
El código es seguro frente a excepciones si funciona correctamente incluso cuando las funciones a las que llama lanzan excepciones.
- ↑ Lau, Ron (10 de noviembre de 2020). "Seguridad ante excepciones en el mundo de JS" . Medium .
- ↑ Dave Abrahams (2000). Seguridad ante excepciones en componentes genéricos . Programación genérica . Notas de clase en ciencias de la computación . Vol. 1766. Springer . págs. 69–79 . doi : 10.1007/3-540-39953-4_6 . ISBN 978-3-540-41090-4. Consultado el 29 de agosto de 2008 .
- ↑ Colvin, Gregory (1994). "Exception Safe Exception" (PDF) . Documentos del Comité de Estándares de C++ . Consultado el 17 de diciembre de 2021 .
- ↑ Abrahams, David. "STLport: Manejo de excepciones" . www.stlport.org . Consultado el 17 de diciembre de 2021 .
- ↑ Abrahams, Dave; Colvin, Greg. "Cómo hacer que la biblioteca estándar de C++ sea segura ante excepciones" (PDF) . Documentos del Comité de Estándares de C++ . Consultado el 17 de diciembre de 2021 .
- 1 2 Crichton, Alex (24 de julio de 2015). "Rust RFC: Estabilizar catch_panic" . El lenguaje de programación Rust . Recuperado el 26 de mayo de 2022 .
- ↑ Bjarne Stroustrup (1997). Apéndice E: Seguridad de excepciones de la biblioteca estándar en "El lenguaje de programación C++" (PDF) (3.ª ed.). Addison-Wesley. ISBN 0-201-88954-4.
- ↑ Austern, Matt (30 de mayo de 1997). "Política de excepciones de la biblioteca estándar" . Documentos del Comité de Estándares de C++ . Recuperado el 26 de mayo de 2022 .
Enlaces externos
- Herb Sutter: C++ excepcional: 47 enigmas de ingeniería, problemas de programación y soluciones, 2000
- Jon Kalb: Programación segura ante excepciones en C++ , con presentaciones de C++Now! 2012 sobre seguridad ante excepciones.
- Discusión relacionada en Stack Overflow: C++: ¿realmente escribes código seguro ante excepciones?
- C++
- Flujo de control
- Temas de lenguajes de programación