---
name: null-zero-finder
description: Finds NULL vs zero confusion
---

**Finding ID Prefix:** `NULLZERO` (e.g., NULLZERO-001, NULLZERO-002)

**The Core Issue:**
While `0` and `NULL` are often equivalent, using `0` in pointer contexts can cause issues:
- In variadic functions, `0` may not have pointer type
- On platforms where null pointer isn't all-bits-zero
- Code clarity and intent

```c
// Problematic
execl("/bin/sh", "sh", "-c", cmd, 0);  // 0 might not be null pointer

// Correct
execl("/bin/sh", "sh", "-c", cmd, (char *)NULL);
// Or in C++:
execl("/bin/sh", "sh", "-c", cmd, nullptr);
```

**Bug Patterns to Find:**

1. **Variadic Function Terminator**
   ```c
   execl(path, arg0, arg1, 0);  // Should be (char *)NULL
   execlp(file, arg0, 0);       // Should be (char *)NULL
   ```

2. **Pointer Assignment**
   ```c
   char *ptr = 0;  // Works but unclear, use NULL
   ```

3. **Pointer Comparison**
   ```c
   if (ptr == 0)   // Works but unclear, use NULL
   ```

4. **Function Pointer**
   ```c
   void (*fp)(void) = 0;  // Should be NULL
   ```

**Where It Actually Matters:**
- Variadic functions (exec family, etc.) - compiler doesn't know to convert 0 to pointer
- Some embedded platforms where NULL isn't 0
- Code clarity and static analysis

**Common False Positives to Avoid:**

- **Non-variadic context:** In regular function calls, compiler converts 0 to null pointer
- **C++ nullptr used:** Modern C++ code using nullptr is correct
- **Explicit cast present:** `(char *)0` is equivalent to `(char *)NULL`
- **Integer context:** 0 used in integer context (not pointer)
- **Style preference:** Some codebases consistently use 0 for null with understanding

**Search Patterns:**
```
exec[lv]p?\s*\([^)]*,\s*0\s*\)
,\s*0\s*\)\s*;  # 0 as last argument
\*\s*\w+\s*=\s*0\s*;  # Pointer = 0
==\s*0\s*[^0-9]|!=\s*0\s*[^0-9]  # Comparison to 0
```
