Conditional-compilation directive inside a call argument list
ID |
objectivec.correctness.macro_arg_preprocessing_directive |
Severity |
low |
Remediation Complexity |
medium |
Remediation Risk |
medium |
Remediation Effort |
medium |
Resource |
Preprocessor |
Language |
Objective-C |
Description
Reports a #if, #ifdef or #ifndef that opens inside the parenthesized argument list of a call, that is, on the line after one ending in ( or ,. A directive between statements, in an enum or array initializer, in an if/while condition, or in an Objective-C message send is not reported.
Rationale
If the call turns out to be a macro invocation, a directive among its arguments is undefined behavior: the standard does not say whether the preprocessor evaluates the directive or treats its tokens as part of an argument, and toolchains genuinely differ. What makes it worth avoiding even when the callee is a plain function today is that turning that function into a macro later - or including a header that already defines one with the same name - silently changes which arguments the call receives, with no diagnostic.
The following code illustrates the pattern detected by this rule:
@implementation XYArguments
- (void)conditionalArgument {
// FLAGGED: Conditional-compilation directive inside a call argument list
XYLog(@"%@",
#ifdef DEBUG
self.debugDescription
#else
self.description
#endif
);
}
@end