8.2 KiB
8.2 KiB
description
| description |
|---|
| Ejecuta cppcheck en código C++ y analiza resultados |
Lint cppcheck Command
Ejecuta análisis estático con cppcheck en código C++, filtra noise, e identifica issues reales relacionados con bugs, memory safety y undefined behavior.
Propósito
cppcheck detecta:
- Memory leaks y resource leaks
- Null pointer dereferences
- Buffer overflows y array bounds issues
- Uninitialized variables
- Dead code y unused functions
- Style issues y code smells
- Undefined behavior
Workflow de Ejecución
-
Solicitar archivos/rutas al usuario (si no se especifican)
- Pedir rutas de archivos
.cpp/.hppo carpetas a analizar - Preguntar nivel de análisis (warning/all/unused)
- Default:
-w(warning, style, performance)
- Pedir rutas de archivos
-
Validar precondiciones
- Confirmar que los archivos/carpetas existen
- Si no existe
build/compile_commands.json, el script lo generará automáticamente
-
Ejecutar cppcheck
# Para archivo específico tools/linter/run_cppcheck.sh -w --path source/game/entities/player.cpp # Para carpeta tools/linter/run_cppcheck.sh -w --path source/game/entities/ # Proyecto completo (LENTO) tools/linter/run_cppcheck.sh -w -
Leer archivo de resultados
-w:tools/linter/cppcheck-result-warning-style-performance.txt-a:tools/linter/cppcheck-result-all.txt-u:tools/linter/cppcheck-result-unusedFunction.txt
-
Analizar y clasificar issues
- Parsear formato de cppcheck:
[archivo:línea]: (severidad) mensaje - Filtrar falsos positivos conocidos
- Agrupar por categoría
- Parsear formato de cppcheck:
-
Presentar resumen al usuario
- Mostrar issues críticos primero
- Explicar contexto cuando sea relevante
- Sugerir acciones correctivas
Niveles de Análisis
-w / --warning (Recomendado para uso diario)
- Velocidad: Rápido
- Checks: warning, style, performance
- Uso: Refactoring diario, antes de commits
- Ejemplo:
tools/linter/run_cppcheck.sh -w --path source/game/entities/player.cpp
-a / --all (Análisis exhaustivo)
- Velocidad: Lento
- Checks: Todos los checks disponibles
- Uso: Después de cambios mayores, auditorías de código
- Ejemplo:
tools/linter/run_cppcheck.sh -a --path source/game/
-u / --unused (Funciones no usadas)
- Velocidad: Medio
- Checks: unusedFunction
- Uso: Limpieza de código muerto
- Ejemplo:
tools/linter/run_cppcheck.sh -u - Nota: Requiere análisis de proyecto completo
Falsos Positivos Conocidos
unusedFunction en métodos públicos
- Contexto: Métodos de API pública, callbacks, getters/setters
- Ejemplo:
Player::getX()usado desde múltiples lugares - Acción: Ignorar si el método es parte de la interfaz pública
passedByValue para tipos pequeños
- Contexto: SDL_FRect, SDL_Point, enums, small structs
- Ejemplo:
void setPos(SDL_FPoint pos) - Acción: Aceptable para tipos ≤ 16 bytes en game code
constParameter en APIs consistentes
- Contexto: Parámetros que no se modifican pero mantienen consistencia de API
- Acción: Opcional, depende de estilo del proyecto
variableScope en inicializaciones complejas
- Contexto: Variables declaradas antes de inicialización compleja
- Acción: Revisar caso por caso, puede ser falso positivo
Categorización de Issues
🔴 Críticos (Requieren corrección inmediata)
error: Bugs confirmadosmemleakOnRealloc: Memory leaksnullPointer: Null pointer dereferencesbufferAccessOutOfBounds: Buffer overflowsuninitvar: Variables no inicializadasuseAfterFree: Use-after-free
🟠 Advertencias (Revisar y corregir)
warning: Potenciales problemasmemleak: Posibles memory leaksresourceLeak: Resource leaks (file handles, etc.)doubleFree: Double freearrayIndexOutOfBounds: Array bounds issues
🟡 Estilo (Mejoran calidad)
style: Code smellsunusedVariable: Variables no usadasredundantAssignment: Asignaciones redundantesunreadVariable: Variables escritas pero no leídas
🟢 Performance (Optimizaciones)
performance: Optimizaciones de rendimientopassedByValue: Pasar por const& en vez de valuepostfixOperator: Usar prefix++ en vez de postfix++
⚪ Informativo (Opcional)
information: Información generalportability: Problemas de portabilidadunusedFunction: Funciones no usadas (revisar contexto)
Formato de Reporte al Usuario
=== cppcheck Analysis Results ===
📁 Archivos analizados: source/game/entities/player.cpp
📊 Nivel: warning + style + performance
📝 Resultados: tools/linter/cppcheck-result-warning-style-performance.txt
🔴 Errores críticos (2):
player.cpp:156 [error:uninitvar] - Variable 'velocity' no inicializada
player.cpp:234 [error:nullPointer] - Posible null pointer dereference
🟠 Advertencias (3):
player.cpp:89 [warning:memleak] - Posible memory leak en 'sprite_'
player.cpp:178 [warning:arrayIndexOutOfBounds] - Índice fuera de límites
🟡 Estilo (4):
player.cpp:45 [style:unusedVariable] - Variable 'temp' declarada pero no usada
player.cpp:102 [style:redundantAssignment] - Asignación redundante a 'x_'
🟢 Performance (2):
player.cpp:67 [performance:passedByValue] - Pasar 'data' por const& (8 bytes - FALSO POSITIVO)
player.hpp:34 [performance:postfixOperator] - Usar prefix++ en lugar de postfix++
✅ Total: 11 issues
- 2 críticos ❗
- 3 advertencias
- 4 estilo
- 2 performance (1 falso positivo)
---
💡 Acción requerida:
1. ✅ Corregir 2 errores críticos INMEDIATAMENTE
2. ⚠️ Revisar 3 advertencias y corregir si aplica
3. 🔧 Considerar 4 mejoras de estilo
4. ⚡ 1 optimización real de performance (ignorar passedByValue)
📄 Detalles completos en: tools/linter/cppcheck-result-warning-style-performance.txt
Acciones Post-Análisis
Si hay errores críticos:
- Mostrar código afectado con contexto
- Explicar el problema en términos claros
- Sugerir corrección específica
- Ofrecer aplicar fix si es sencillo
Si solo hay warnings/style:
- Resumir issues por categoría
- Indicar prioridades (qué corregir primero)
- Explicar falsos positivos identificados
- Preguntar si aplicar fixes para issues simples
Si no hay issues:
✅ ¡Código limpio! No se encontraron issues.
Ejemplos de Correcciones Comunes
Uninitialized variable
// ❌ Antes
int velocity;
if (condition) {
velocity = 10;
}
use(velocity); // Error: puede estar no inicializada
// ✅ Después
int velocity{0}; // Inicializar en declaración
if (condition) {
velocity = 10;
}
use(velocity);
Memory leak
// ❌ Antes
void loadTexture() {
texture_ = new SDL_Texture(...);
if (error) return; // Leak si hay error después
}
// ✅ Después
void loadTexture() {
auto temp = std::make_unique<SDL_Texture>(...)
if (error) return; // RAII - se libera automáticamente
texture_ = std::move(temp);
}
Null pointer dereference
// ❌ Antes
Player* player = getPlayer();
player->update(); // Puede ser nullptr
// ✅ Después
Player* player = getPlayer();
if (player != nullptr) {
player->update();
}
Integración con Workflow
Cuándo ejecutar:
- Después de refactoring - Verificar que no se introdujeron bugs
- Antes de commit - Análisis
-wrápido - Antes de PR - Análisis
-acompleto - Periódicamente - Análisis
-upara limpieza de código
Integración con /refactor-class:
El comando /refactor-class ejecuta automáticamente:
tools/linter/run_cppcheck.sh -w --path <archivo_refactorizado>
Notas Importantes
- Genera archivos de salida en
tools/linter/cppcheck-result-*.txt - Auto-genera compile_commands.json si no existe
- Paralelización automática usa N-1 cores
- Suppressions file excluye external/ y system headers
- Contexto importa - Revisar falsos positivos manualmente
- No modifica código - Solo reporta, no aplica fixes automáticos
Uso:
/lint-cppcheck
(El comando preguntará qué analizar y qué nivel usar)
O especificar directamente:
/lint-cppcheck source/game/entities/player.cpp