preprocessor-toolchain · beginner · ~15 min

Parenthesized Clamp Macro

Master function-like macro hygiene and prevent operator precedence bugs with strict parameter and expression parenthesization.

Challenge

Function-like macros without comprehensive parentheses cause subtle precedence bugs when invoked with expressions containing binary operators. Defensive macro hygiene requires wrapping every parameter and the entire macro body in parentheses.

Your Task

Define two safe function-like macros:

#define SAFE_SQUARE(x) ...
#define SAFE_CLAMP(val, low, high) ...

And implement a wrapper function:

int compute_clamped_square(int x, int low, int high);

Rules

  1. SAFE_SQUARE(x) must calculate the square of x, working correctly for expressions like SAFE_SQUARE(1 + 2) (which must evaluate to 9, not 1 + 2 * 1 + 2 = 5).
  2. SAFE_CLAMP(val, low, high) must clamp val between low and high:
    • If val < low, evaluate to low.
    • If val > high, evaluate to high.
    • Otherwise evaluate to val.
    • Expressions passed as parameters must not suffer from operator precedence issues.
  3. compute_clamped_square(x, low, high) must compute SAFE_SQUARE(x) and clamp the result using SAFE_CLAMP(square, low, high).

Example

compute_clamped_square(5, 0, 20); // 5*5=25, clamped to 20
compute_clamped_square(3, 10, 50); // 3*3=9, clamped to 10

Input format

x: base integer; low: minimum bound; high: maximum bound.

Output format

Returns clamped squared value as integer.

Constraints

Both macros must be fully parenthesized.

Starter code

/* Define SAFE_SQUARE and SAFE_CLAMP macros here */
#define SAFE_SQUARE(x) 0
#define SAFE_CLAMP(val, low, high) 0

int compute_clamped_square(int x, int low, int high) {
    (void)x; (void)low; (void)high;
    return 0;
}

Common mistakes

Forgetting parentheses around parameter usages: x * x instead of ((x) * (x)); forgetting outer parentheses around macro body.

Edge cases to handle

Negative values squared become positive; low > high behavior handled by ternary ordering; compound expressions as macro arguments.

Background lessons

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