preprocessor-toolchain · beginner · ~15 min
Master function-like macro hygiene and prevent operator precedence bugs with strict parameter and expression parenthesization.
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.
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);
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).SAFE_CLAMP(val, low, high) must clamp val between low and high:val < low, evaluate to low.val > high, evaluate to high.val.compute_clamped_square(x, low, high) must compute SAFE_SQUARE(x) and clamp the result using SAFE_CLAMP(square, low, high).compute_clamped_square(5, 0, 20); // 5*5=25, clamped to 20
compute_clamped_square(3, 10, 50); // 3*3=9, clamped to 10
x: base integer; low: minimum bound; high: maximum bound.
Returns clamped squared value as integer.
Both macros must be fully parenthesized.
/* 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;
}
Forgetting parentheses around parameter usages: x * x instead of ((x) * (x)); forgetting outer parentheses around macro body.
Negative values squared become positive; low > high behavior handled by ternary ordering; compound expressions as macro arguments.
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.