Macro parameter used as an operand without its own parentheses
ID |
objectivec.correctness.macro_parentheses |
Severity |
low |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Preprocessor |
Language |
Objective-C |
Description
Reports a function-like #define in which a parameter is written next to an arithmetic, bitwise, relational or equality operator without parentheses of its own. A parameter that is always written (param) is not reported, and neither is a parameter used only as a call argument, an array subscript, a member access, a stringify or paste operand, or a value macro with no parameter list. Only single-line definitions are examined.
Rationale
A macro is expanded by text substitution before the compiler sees any grouping, so the argument arrives as raw tokens and re-associates with whatever surrounds it. #define SQUARE(x) x * x turns SQUARE(a + b) into a + b * a + b, which is a + (b * a) + b - the wrong value, computed without any warning at either the definition or the call. Wrapping the whole body helps but is not enough: (x * x) still expands to (a + b * a + b). The bug only appears for arguments that are themselves expressions, so it survives every test that passes a plain variable and surfaces later, far from the macro.
The following code illustrates the pattern detected by this rule:
// FLAGGED: Macro parameter used as an operand without its own parentheses
#define XY_SQUARE(x) x * x