basics · beginner · ~10 min

Spot the signed/unsigned compare trap

Recognize implicit conversion in signed/unsigned compares.

Challenge

Compare a signed int against an unsigned size_t correctly, avoiding C's implicit-conversion trap where -1 < 5u evaluates to false.

Task

Implement int safer_lt(int a, size_t b) that returns 1 if a is mathematically less than b, else 0. The catch: in a naive a < b, C promotes a to size_t, so -1 becomes SIZE_MAX and the comparison is wrong. Handle the sign of a explicitly before any unsigned comparison.

Input

A signed int a and an unsigned size_t b.

Output

Returns 1 when a < b mathematically, otherwise 0. Any negative a is less than any (non-negative) b.

Example

safer_lt(-1, 5)     ->   1     (naive a < b would wrongly give 0)
safer_lt(5, 10)     ->   1
safer_lt(10, 5)     ->   0
safer_lt(0, 0)      ->   0
safer_lt(0, 1)      ->   1

Edge cases

  • Negative a (including INT_MIN) is always less than any size_t.
  • a == 0, b == 0 returns 0.
  • Large b near SIZE_MAX must compare correctly.

Rules

  • Do not paper over the rule with a single cast — branch on the sign of a first.

Why this matters

if (signed_var < unsigned_var) triggers implicit conversion that flips negative numbers to huge positives. Real-world CVEs (e.g. in mmap-size validation) come from this.

Input format

A signed int a and an unsigned size_t b.

Output format

1 if a is mathematically less than b, otherwise 0.

Constraints

Handle negative a before any unsigned comparison; no casts that hide the rule.

Starter code

#include <stddef.h>
int safer_lt(int a, size_t b) { /* TODO */ return 0; }

Common mistakes

Writing the naïve return a < b; and not catching that -1 < (size_t)5 evaluates false because (size_t)-1 == SIZE_MAX.

Edge cases to handle

a == INT_MIN; a == 0, b == 0; large b near SIZE_MAX.

Complexity

O(1).

Background lessons

Up next

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.