Why does EK9 reject comparisons against variables with known constant values?

← Data Flow Safety · Ref: Q796

EK9 tracks variable assignments through data flow analysis. When a variable is assigned a constant value and then compared, the compiler can determine whether the condition is always true or always false.

ALWAYS TRUE (E08086)

  status <- "active"
  if status == "active"   dead else branch

ALWAYS FALSE (E08087)

  status <- "active"
  if status == "error"    dead if body

WHY REJECTED

Dead branches indicate logic errors. Either the condition is wrong, the variable should have a different value, or the check is unnecessary.

CORRECT PATTERNS

- Use parameters instead of constants when conditions should vary
- Use the constant directly if one branch is never needed
- Check a different variable that can actually change

See Q795 for logical tautology. See Q632 for define-before-use.

Example

defines module qa.dataflowsafety.conditionalways

  defines function

    lookupMode()
      -> modeCode as Integer
      <- rtn as String: String()

      if modeCode > 0
        rtn: "active"
      else
        rtn: "inactive"

    lookupChannel()
      -> channelId as Integer
      <- rtn as String: String()

      if channelId > 0
        rtn: "open"
      else
        rtn: "closed"

    checkMode()
      -> modeCode as Integer
      <- label as String: String()

      currentMode <- lookupMode(modeCode)

      if currentMode == "active"
        label: "System is active"
      else
        label: "System is inactive"

    checkChannel()
      -> channelId as Integer
      <- label as String: String()

      channelState <- lookupChannel(channelId)

      if channelState == "closed"
        label: "Channel closed"
      else
        label: "Channel available"

Common mistakes

E08086 — When the compiler tracks that 'currentMode' was assigned the constant 'active', the condition 'currentMode == "active"' is always true, making the else branch unreachable dead code. Use a computed value instead. See ek9 -h E08086 for details.

Incorrect:

      currentMode <- "active"

Correct:

      currentMode <- lookupMode(modeCode)

E08087 — When the compiler tracks that 'channelState' was assigned the constant 'open', the condition 'channelState == "closed"' is always false, making the if body unreachable dead code. Use a computed value instead. See ek9 -h E08087 for details.

Incorrect:

      channelState <- "open"

Correct:

      channelState <- lookupChannel(channelId)
Other ways to ask this
  • What triggers E08086 condition always true?
  • What triggers E08087 condition always false?
  • How does EK9 track variable values through data flow?

Coming from another language?

Java: no compiler detection, relies on FindBugs. Python: no detection. Rust: compiler does not warn for this pattern. Kotlin: IntelliJ may warn but compiles. Go: no detection. EK9: compile-time error E08086/E08087, prevents dead branches from reaching production.

Keywords: dead, condition, true, E08087, E08086, false, branch, always, flow