Últimamente he estado luchando por comprender cuál es la cantidad correcta de verificación y cuáles son los métodos adecuados.
Tengo algunas preguntas al respecto:
¿Cuál es la forma correcta de verificar los errores (entrada incorrecta, estados incorrectos, etc.)? ¿Es mejor verificar explícitamente los errores o utilizar funciones como afirmaciones que se pueden optimizar a partir de su código final? Siento que verifica explícitamente el desorden de un programa con una gran cantidad de código adicional que no debería ejecutarse en la mayoría de las situaciones de todos modos, y sin mencionar que la mayoría de los errores terminan con una falla de anulación / salida. ¿Por qué saturar una función con comprobaciones explícitas solo para abortar? He buscado afirmaciones versus verificación explícita de errores y encontré poco para explicar realmente cuándo hacerlo.
La mayoría dice 'use afirmaciones para verificar errores lógicos y usa verificaciones explícitas para verificar otras fallas'. Sin embargo, esto no parece llevarnos muy lejos. Diríamos que esto es factible:
Malloc returning null, check explictly
API user inserting odd input for functions, use asserts
¿Me mejoraría esto en la comprobación de errores? ¿Que más puedo hacer? Realmente quiero mejorar y escribir mejor, código 'profesional'.
fuente
setjmp
/longjmp
están disponibles en C, por lo que no necesita un nuevo lenguaje.Respuestas:
La forma más fácil para que yo sepa la diferencia es determinar si la condición de error se introduce en tiempo de compilación o en tiempo de ejecución. Si el problema es que un programador usa la función de manera incorrecta, haga una afirmación para llamar la atención sobre el problema, pero una vez que la solución se compila en el código de llamada, ya no tiene que preocuparse por verificarlo. Los problemas como la falta de memoria o la entrada incorrecta del usuario final no se pueden resolver en el momento de la compilación, por lo que debe dejar los controles.
fuente
Verifique cualquier cosa en cualquier momento (podría haber cambiado después de su última verificación) que no esté 100% bajo su comando. Y también: ¡Durante el desarrollo, incluso no confíes en ti mismo! ;-)
Okokok ... "cualquier cosa" está destinada a leerse como una comprobación de las cosas que causarían un aborto anormal o cualquier cosa que pueda hacer que su aplicación / sistema haga cosas que no debería hacer.
Para ser serios, la última parte de la última oración es esencial porque señala el problema principal:
Si desea construir un sistema estable, la principal preocupación no es lo que debe hacer el sistema, sino dejar que pueda hacer cosas tan obligatorias, uno debe ocuparse de lo que no debe hacer, incluso si "abarrota su código".
fuente
El quid de la gestión de errores no es si y cómo atrapar el problema. Es más de lo que haces después de que te enteras .
En primer lugar, diría que no hay ninguna razón por la cual un solo error devuelto por el método subordinado está regresando no debería ser manejado. Y los errores y las excepciones son más que los valores de retorno o todos los intentos / capturas.
Solo lanzar y atrapar no es suficiente.
Vea esto : donde el autor explica que solo atrapar pero no hacer nada potencialmente suprime la excepción y, a menos que se haga lo suficiente para deshacer el daño, es peor que dejar que el código funcione así. De manera similar, simplemente escribir la declaración "log" cuando hay un archivo abierto o un error de lectura podría ayudar a encontrar la razón, pero para cuando el programa finaliza, ¡podría haber causado que los datos se dañen! No es suficiente decir que tengo muchos intentos / capturas, ¡es más importante saber lo que realmente hacen!
No abuses del intento y atrapa.
Algunas veces, la mayoría de los programadores perezosos o ingenuos piensan que después de escribir suficiente try / catch, su trabajo ha terminado y es fácil. Muy a menudo es mejor aplicar acciones correctivas y reanudar en lugar de simplemente deshacerse de todo. Si esto no se puede hacer, uno debe decidir a qué nivel necesita regresar. Dependiendo del contexto y la gravedad, intente capturar anidamiento necesita un diseño cuidadoso. Por ejemplo: vea esto y esto
Defina quién es responsable:
Una de las primeras cosas que debe hacer es definir si la entrada dada a la rutina en sí misma es solo un escenario inaceptable (o no manejado hasta ahora) o es la excepción debido al entorno (como un problema del sistema, un problema de memoria), o Es esta situación un resultado completamente interno que surge del algoritmo. En todos los casos, el nivel al que desea regresar o la acción que desea tomar difiere significativamente. Desde este punto de vista, me gustaría decir que cuando ejecuta el código en producción, hacer que abort () salga del programa es bueno, pero no para cada pequeña cosa. Si detecta daños en la memoria o falta de memoria, es definitivo que incluso después de hacer lo mejor que pueda, las cosas morirán. Pero si recibe un puntero NULL en la entrada, no lo haría
Defina cuál es el mejor resultado posible:
lo que todas las cosas deben hacerse bajo excepción es muy crítico. Por ejemplo, si en uno de nuestros casos, un reproductor de medios descubre que no tiene datos completos para ser reproducidos por el usuario, ¿qué debe hacer?
Todos estos son subjetivos, y tal vez hay más formas de manejar los problemas de lo que trivialmente creemos. Todo lo anterior requiere construir y comprender la profundidad de la excepción y, además, hacer que los diferentes escenarios sean posibles para evolucionar.
A veces necesitamos verificar las excepciones antes de que surjan. El ejemplo más común es el error dividir por cero. Idealmente, uno debe probar eso antes de que se produzca dicha excepción, y si ese es el caso, ¡trate de poner el valor distinto de cero más apropiado y seguir adelante en lugar de suicidarse!
Limpiar. ¡Al menos esto es lo que debes hacer! Si una función abre 3 archivos y el cuarto no se abre, no hace falta decir que los primeros 3 deberían haberse cerrado. Delegar este trabajo a una capa de arriba es una mala idea. si decides no marcharte sin limpiar la memoria. Y lo más importante: incluso si ha sobrevivido a la excepción, informe a los superiores que las cosas no han tomado el curso normal.
La forma en que vemos la funcionalidad (normal) del software en términos de varias jerarquías o capas o abstracciones, de la misma manera que debemos categorizar las excepciones en función de su gravedad y el alcance bajo el cual surgen y están afectando otras partes del sistema, eso define cómo manejar excepciones tan diferentes de la mejor manera posible.
Mejor referencia: Code Craft capítulo 6 - disponible para descargar
fuente
La comprobación de errores solo durante las compilaciones de depuración es una MALA IDEA (tm), que se compila bajo la versión superpuesta de variables reutilizables en la pila, elimina las páginas de protección, hace dudosos trucos con cálculos, reemplaza artríticas pesadas con cambios precalculados, etc.
Utilice la comprobación de errores en la versión también, puede recurrir a algo tan simple como:
Esto también tiene un efecto secundario muy bueno que definitivamente no ignorará el error una vez que la aplicación comience a fallar en la PC de Betta Testers.
Los espectadores y registros de eventos son completamente inútiles en comparación con
abort()
, ¿quién los revisa de todos modos?fuente
abort
rompe en depurador / crea un volcado.exit
es malo si. Aunque, prefiero__asm int 3
más.Las diversas cosas que puede hacer es
1. Leer y asimilar gran cantidad de código en línea y ver cómo se hace.
2. Usar algunas herramientas de depuración para ayudarlo a localizar regiones de errores
3. Tenga en cuenta los errores triviales debido a asignaciones incorrectas y errores de sintaxis
4. Algunos errores peores surgen debido a errores lógicos en el programa que son más difíciles de encontrar. Para esto, puede localizarlo y encontrarlo o, para los más complicados, intente hablar con la gente o usar recursos como Stackoverflow , Wikipedia , google para obtener ayuda de personas.
fuente