276 lines
8.2 KiB
Markdown
276 lines
8.2 KiB
Markdown
---
|
|
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
|
|
|
|
1. **Solicitar archivos/rutas al usuario** (si no se especifican)
|
|
- Pedir rutas de archivos `.cpp`/`.hpp` o carpetas a analizar
|
|
- Preguntar nivel de análisis (warning/all/unused)
|
|
- Default: `-w` (warning, style, performance)
|
|
|
|
2. **Validar precondiciones**
|
|
- Confirmar que los archivos/carpetas existen
|
|
- Si no existe `build/compile_commands.json`, el script lo generará automáticamente
|
|
|
|
3. **Ejecutar cppcheck**
|
|
```bash
|
|
# 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
|
|
```
|
|
|
|
4. **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`
|
|
|
|
5. **Analizar y clasificar issues**
|
|
- Parsear formato de cppcheck: `[archivo:línea]: (severidad) mensaje`
|
|
- Filtrar falsos positivos conocidos
|
|
- Agrupar por categoría
|
|
|
|
6. **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 confirmados
|
|
- `memleakOnRealloc`: Memory leaks
|
|
- `nullPointer`: Null pointer dereferences
|
|
- `bufferAccessOutOfBounds`: Buffer overflows
|
|
- `uninitvar`: Variables no inicializadas
|
|
- `useAfterFree`: Use-after-free
|
|
|
|
### 🟠 Advertencias (Revisar y corregir)
|
|
- `warning`: Potenciales problemas
|
|
- `memleak`: Posibles memory leaks
|
|
- `resourceLeak`: Resource leaks (file handles, etc.)
|
|
- `doubleFree`: Double free
|
|
- `arrayIndexOutOfBounds`: Array bounds issues
|
|
|
|
### 🟡 Estilo (Mejoran calidad)
|
|
- `style`: Code smells
|
|
- `unusedVariable`: Variables no usadas
|
|
- `redundantAssignment`: Asignaciones redundantes
|
|
- `unreadVariable`: Variables escritas pero no leídas
|
|
|
|
### 🟢 Performance (Optimizaciones)
|
|
- `performance`: Optimizaciones de rendimiento
|
|
- `passedByValue`: Pasar por const& en vez de value
|
|
- `postfixOperator`: Usar prefix++ en vez de postfix++
|
|
|
|
### ⚪ Informativo (Opcional)
|
|
- `information`: Información general
|
|
- `portability`: Problemas de portabilidad
|
|
- `unusedFunction`: 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:
|
|
1. **Mostrar código afectado** con contexto
|
|
2. **Explicar el problema** en términos claros
|
|
3. **Sugerir corrección** específica
|
|
4. **Ofrecer aplicar fix** si es sencillo
|
|
|
|
### Si solo hay warnings/style:
|
|
1. **Resumir issues** por categoría
|
|
2. **Indicar prioridades** (qué corregir primero)
|
|
3. **Explicar falsos positivos** identificados
|
|
4. **Preguntar si aplicar fixes** para issues simples
|
|
|
|
### Si no hay issues:
|
|
```
|
|
✅ ¡Código limpio! No se encontraron issues.
|
|
```
|
|
|
|
## Ejemplos de Correcciones Comunes
|
|
|
|
### Uninitialized variable
|
|
```cpp
|
|
// ❌ 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
|
|
```cpp
|
|
// ❌ 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
|
|
```cpp
|
|
// ❌ 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:
|
|
|
|
1. **Después de refactoring** - Verificar que no se introdujeron bugs
|
|
2. **Antes de commit** - Análisis `-w` rápido
|
|
3. **Antes de PR** - Análisis `-a` completo
|
|
4. **Periódicamente** - Análisis `-u` para limpieza de código
|
|
|
|
### Integración con `/refactor-class`:
|
|
|
|
El comando `/refactor-class` ejecuta automáticamente:
|
|
```bash
|
|
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
|
|
```
|