magic number detection

**Magic Number Detection** is the **automated identification of literal numeric constants and undocumented string literals hardcoded directly in program logic** — detecting the code smell where values like `86400`, `3.14159`, `0x1F4`, or `"application/json"` appear without explanation in conditional checks, calculations, or configuration, forcing every reader to reverse-engineer the meaning and every maintainer to hunt down every occurrence when the value needs to change. **What Is a Magic Number?** A magic number is any literal value whose meaning is not self-evident from context: - **Time Constants**: `if elapsed > 86400:` — What is 86400? Why 86400 and not 86401? Is it seconds, milliseconds, or microseconds? - **Business Rules**: `if score > 750:` — What does 750 represent? A credit score threshold? A game level? A database limit? - **Protocol Values**: `if status == 404:` — Status codes are standard but `if retries == 5:` is magic — why 5? - **Mathematical Constants**: `area = radius * 3.14159 * radius` — π hardcoded, inconsistently precise across the codebase. - **Bit Flags**: `if flags & 0x08:` — What does the 4th bit represent? **Why Magic Number Detection Matters** - **Undocumented Business Rules**: The most dangerous magic numbers encode business rules that exist nowhere else in the system documentation. When compliance requirements or business policies change, developers must find every hardcoded instance rather than changing a single named constant. Miss one occurrence and the behavior is inconsistently applied. - **Readability Tax**: Every magic number requires the reader to pause and decode meaning before continuing. A function with 5 magic numbers imposes 5 comprehension pauses. Named constants (`SECONDS_PER_DAY = 86400`) make the intent explicit at the point of use without requiring lookup. - **Type Safety Bypass**: Named constants in typed languages carry type information as well as meaning. `TIMEOUT_MS = 5000` in TypeScript documents that the value is milliseconds. `5000` is ambiguous — is it milliseconds, seconds, or a retry count? Magic numbers remove type semantic context. - **Multi-Site Change Risk**: When a magic number must change, the developer must use Find-Replace across the codebase — a deeply unsafe operation because `5` appears as `5` in contexts completely unrelated to the business rule they're changing. Named constants localize change to a single definition site. - **Test Brittleness**: Tests that hardcode magic numbers in assertions (`assert result == 3.14`) break when the calculation logic improves precision or when the business value changes, even though the improvement is correct. Testing against named constants (`assert result == EXPECTED_AREA`) survives refactoring. **Detection Rules** Standard linting configurations flag: - Any integer literal except `0`, `1`, `-1` (which are universally understood) - Any float literal except `0.0`, `1.0`, `0.5` in some contexts - Any string literal except empty string `""` and `"true"/"false"` booleans - Repeated literals: the same literal appearing 3+ times across a file or module **Legitimate Exceptions** - Mathematical algorithms where the constants are part of a standard formula and are named in comments - Test data where literal values are intentional and documented - Lookup tables where the literals are the data, not embedded logic **Refactoring Pattern** ```python # Before: Magic Number if user.age < 18: # Why 18? redirect("parental_consent") if account.balance < 500: # Why 500? USD? Cents? charge_fee(25) # Why 25? # After: Named Constants MINIMUM_AGE_FOR_CONSENT = 18 MINIMUM_BALANCE_FOR_FREE_TIER_USD = 500 BELOW_MINIMUM_BALANCE_FEE_USD = 25 if user.age < MINIMUM_AGE_FOR_CONSENT: redirect("parental_consent") if account.balance < MINIMUM_BALANCE_FOR_FREE_TIER_USD: charge_fee(BELOW_MINIMUM_BALANCE_FEE_USD) ``` **Tools** - **ESLint (JavaScript/TypeScript)**: `no-magic-numbers` rule with configurable exception list. - **Pylint (Python)**: Magic number detection with threshold configuration. - **PMD (Java)**: `AvoidLiteralsInIfCondition` and related rules. - **SonarQube**: Magic number detection as part of its maintainability rules across all supported languages. - **Checkstyle**: `MagicNumber` rule for Java with configurable ignore values. Magic Number Detection is **demanding context for every literal** — enforcing the discipline that values embedded in logic must be named, documented, and centralized, transforming implicit business rules embedded in code into explicit, locatable, maintainable constants that every reader can understand and every maintainer can change safely.

Go deeper with CFSGPT

Get AI-powered deep-dives, save terms, and run advanced simulations — free account.

Create Free Account