Trigraph sequence in the source text
ID |
objectivec.maintainability.avoid_trigraphs |
Severity |
info |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Obscure Syntax |
Language |
Objective-C |
Description
Reports any of the nine trigraph sequences - ??=, ??/, ??', ??(, ??), ??!, ??<, ??>, ??- - anywhere in the file. Occurrences inside a comment or a string literal are reported as well, because a trigraph is replaced before comments are removed and before string literals are assembled, so it is a trigraph wherever it appears. Two question marks followed by any other character - really?? what now - are not a trigraph and are not reported.
Rationale
A trigraph does not look like the character it becomes, so the text a reader sees is not the text the compiler sees. "Surprising??!" prints Surprising|, and a ??/ at the end of a line is a backslash, which splices the following line onto this one - inside a // comment that quietly swallows the next statement, and inside a string literal it continues the literal. Because the replacement happens in the very first translation phase, no later construct can protect against it, and modern compilers disable trigraphs by default, so the same file means different things depending on the build flags.
The following code illustrates the pattern detected by this rule:
@implementation Legacy
- (void)arrays {
// FLAGGED: Trigraph sequence in the source text
int table??(4??) = {1, 2, 3, 4};
// FLAGGED: Trigraph sequence in the source text
NSLog(@"first %d", table??(0??));
}
@end
Remediation
Write the character the trigraph stands for. ??( and ??) become [ and ], ??< and ??> become { and }, ??= becomes #, ??! becomes |, ??' becomes ^, ??- becomes ~, and ??/ becomes \. Where two question marks are genuinely wanted in text, break the pair with an escape - "Surprising?\?!" - so the sequence can never be read as a trigraph.