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.

Configuration

This detector does not need any configuration.

© 2026 Xygeni. All rights reserved