Programación Defensiva
Técnicas de Aritmética Segura
Comprobación Antes del Cálculo
int safe_multiply(int a, int b) {
if (a > 0 && b > INT_MAX / a) return -1;
if (a < 0 && b < INT_MAX / a) return -1;
return a * b;
}
Estrategias de Detección de Desbordamiento
graph TD
A[Operación Aritmética] --> B{Comprobar Límites}
B -->|Seguro| C[Realizar Cálculo]
B -->|Riesgoso| D[Gestionar Posible Desbordamiento]
Prácticas Recomendadas
| Estrategia |
Descripción |
Ejemplo |
| Comprobación de Rango Explícita |
Validar la entrada antes del cálculo |
Verificar la entrada contra los límites del tipo |
| Conversión Segura |
Usar conversiones de tipo cuidadosas |
Comprobar los rangos de valores durante la conversión |
| Manejo de Errores |
Implementar un manejo robusto de errores |
Devolver códigos de error o usar excepciones |
Implementación de Multiplicación Segura
#include <limits.h>
#include <stdbool.h>
bool safe_multiply(int a, int b, int* result) {
if (a > 0 && b > 0 && a > INT_MAX / b) return false;
if (a > 0 && b < 0 && b < INT_MIN / a) return false;
if (a < 0 && b > 0 && a < INT_MIN / b) return false;
if (a < 0 && b < 0 && a < INT_MAX / b) return false;
*result = a * b;
return true;
}
Advertencias del Compilador y Análisis Estático
Habilitar Comprobaciones de Desbordamiento
gcc -Wall -Wextra -Woverflow -O2 your_program.c
Protección Avanzada contra Desbordamiento
Uso de Funciones Integradas
#include <stdlib.h>
int main() {
int a = 1000000;
int b = 1000000;
int result;
if (__builtin_smul_overflow(a, b, &result)) {
// Gestionar el desbordamiento
fprintf(stderr, "Se detectó un desbordamiento en la multiplicación\n");
}
return 0;
}
Principios de Programación Defensiva
En LabEx, recomendamos:
- Validar siempre los rangos de entrada.
- Usar tipos de datos apropiados.
- Implementar comprobaciones explícitas de desbordamiento.
- Utilizar las advertencias del compilador.
- Realizar pruebas exhaustivas.
Patrón de Manejo de Errores
enum CalculationResult {
CALC_SUCCESS,
CALC_OVERFLOW,
CALC_INVALID_INPUT
};
enum CalculationResult safe_divide(int a, int b, int* result) {
if (b == 0) return CALC_INVALID_INPUT;
if (a == INT_MIN && b == -1) return CALC_OVERFLOW;
*result = a / b;
return CALC_SUCCESS;
}