Errores en software Errores y excepciones • 1945 • Mark II • Harvard Programación Orientada a Objeto Ing. Civil en Telecomunicaciones Errores en software Errores en software • 1962: Mariner I cae a la tierra por error de transcripción de una fórmula • 1982: CIA introduce error en computador canadiense usado por gasoducto soviético • 1982: H.M.S. Sheffield destruido porque software marca al Exocet como “amistoso” • 1996: Ariane 5 destruido por error en software • 1999: Mars Climate Orbiter choca con Marte por error en conversión de unidades • Errores son inevitables Errores en software Fuentes de errores • Los programas deberían • Errores en especificación Producir los resultados esperados para todas las entradas esperadas Producir mensajes de error apropiados para entradas no esperadas • Además, sus programas deberían No preocuparse de errores en hardware No preocuparse de errores en otro software Terminar si ocurre un error © 2015 Mario Medina C. Pero son manejables • Organizar software para minimizar errores • Eliminar mayoría de errores “importantes” depuración (debugging) prueba y verificación (testing) • Manejo de errores es el 95% del esfuerzo en el desarrollo profesional de software “Qué hace el programa?” • Implementaciones incompletas “Ese caso no ocurre nunca” • Argumentos inesperados “Nadie calculará sqrt(-1)” • Entradas inesperadas “Usuario deberá ingresar un entero” 1 Qué hacer para eliminar errores? Tipos de errores • Organizar software para eliminar errores • Errores de tiempo de compilación Programación modular, estructurada, orientada-a-objetos, etc. • Eliminar (mayoría de) errores mediante depuración y ensayo • Asegurar que los errores que queden no sean críticos Errores de sintaxis Errores de tipo • Errores de tiempo de enlazado • Errores de tiempo de ejecución Detectados por computador (se cae!) Detectados por biblioteca (excepciones) Detectados por programa del usuario • Errores de lógica del programa Detectados por el programador Errores de tiempo de compilación • Ejemplos Errores en argumentos a funciones Errores en datos desde flujos (archivos) • Verificar argumentos a funciones • Compilador puede ayudar! Verifica número y tipo de los argumentos Alternativas para area(7, -10) • “Ud. no lo haga!” • Función que invoca a area() debe verificar los argumentos No siempre se hace • Función area() verifica los argumentos Retorna un código de error Solución no es general Modifica un indicador de estado de error Solución no es general Ejemplo: errores en argumentos int area(int largo, int ancho) { return largo*ancho; } int s1 = area(7); int s2 = area(“siete”, 2); int s3 = area(7.5, 10); int s4 = area(7, -10); • Los 3 primeros casos pueden ser detectados por el compilador Informando sobre errores • Retorna un código de error Debe ser verificado al invocar función int area(int largo, int ancho) { if (largo <= 0 || ancho <= 0) return -1; // Valor no válido return largo*ancho; } // Programa principal int x = area(a, b); if (x < 0) cerr << “Error en area” << endl; Generar una excepción © 2015 Mario Medina C. 2 Informando sobre errores • Modifica indicador de estado de error Debe ser verificado al invocar la función int errno = 0; int area(int largo, int ancho) { if (largo <= 0 || ancho <= 0) errno = -7; return largo*ancho; } // Programa principal int x = area(a, b); if (errno != 0) cerr << “Error en area” << endl; Informando sobre errores • Programa arroja una excepción Debe ser atrapada en alguna parte del programa class ErrorEnArea{}; // Objeto excepcion int area(int largo, int ancho) { if (largo <= 0 || ancho <= 0) throw ErrorEnArea(); return largo*ancho; } // Programa principal try { int x = area(a, b); } catch(ErrorEnArea) { cerr << “Error en area” << endl; } Excepciones encadenadas using namespace std; int main() { . . . . try { vector<int> v; int x; while(cin >> x) { v.push_back(x); } for (int i = 0; i <= v.size(); ++i) cout << “v[“ << i << “] == “ << v[i] << endl; } © 2015 Mario Medina C. Problemas de enfoques anteriores • Retorno de código de error Qué pasa si programa no verifica el valor retornado por la función? Qué pasa si función no tiene valores inválidos para usar como indicador de error? • Indicador de error errno Qué pasa si programa no verifica errno? Cómo elegir un número apropiado que almacenar en errno? Dónde se generó el error indicado por errno? Excepciones • C++ usa excepciones como su método general para manejo de errores Pueden ser usadas para informar de cualquier tipo de error Separan detección de error (función llamada) con atención del error (función llamadora) Toda excepción generada via throw debe ser atrapada en alguna parte del código usando try . . . catch Excepciones encadenadas catch(out_of_range) { cerr << “Error de rango” << endl; return 1; } catch(domain_error e){ cerr << “Error: ” << e.what() << endl; return 2; } catch(. . .){ cerr << “Otro error!” << endl; return 3; } 3 Excepción domain_error Excepción domain_error • Excepción domain_error • Recibe como argumento un string describiendo el error Declarada en <stdexcept> • Incluida en la biblioteca estandar STL • Creada para ser arrojada por aplicaciones desarrolladas usando STL Ninguna función de la STL arroja este tipo de excepciones Excepción domain_error Accesible mediante función miembro what() • Fácil de usar • Recomendada para su uso en los programas a desarrollar en este curso Otras excepciones útiles • Ejemplo con excepción domain_error #include <stdexcept>; int area(int largo, int ancho) { if (largo <= 0 || ancho <= 0) throw domain_error(“Error en area()”); return largo*ancho; } // Programa principal try { int x = area(a, b); } catch(domain_error e) { cerr << e.what() << endl; } • Excepciones generadas por una violación de la lógica del programa (logic_error) logic_error domain_error invalid_argument length_error out_of_range future_error Otras excepciones útiles • Excepciones generadas al ejecutar el programa (runtime_error) logic_error overflow_error underflow_error system_error range_error © 2015 Mario Medina C. 4