Unsigned variable initialised from a literal with no U suffix
ID |
objectivec.maintainability.unsigned_literal_suffix |
Severity |
info |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Numeric Literal |
Language |
Objective-C |
Description
Reports a declaration whose type is unsigned - NSUInteger, size_t, unsigned, uint32_t and the other fixed-width unsigned spellings - initialised from a plain decimal literal carrying no u, U, ul or ull suffix. A literal that already has a suffix, a lone 0, a hexadecimal literal, an initialiser that is an expression rather than a single literal, and a signed type are not reported. Assignments to a variable declared elsewhere are outside the rule’s reach, since the type is only visible at the declaration.
Rationale
A plain decimal literal has a signed type, so an unsigned variable initialised from one forces a conversion the source does not show. That conversion is silent and usually harmless, but it stops being harmless where the value approaches the limits of the type: a literal that will not fit in an int changes type on its own, and once the literal is reused in mixed signed and unsigned arithmetic the usual conversions can turn a subtraction into a very large positive number. Suffixing the literal makes the intended type explicit and keeps the declaration self-describing.
The following code illustrates the pattern detected by this rule:
// FLAGGED: Unsigned variable initialised from a literal with no U suffix
static const NSUInteger kDefaultRetries = 3;
Remediation
Add the suffix that matches the declared type - 3u for unsigned int and NSUInteger, 128UL for unsigned long and size_t, 900000ULL for unsigned long long. Where the value is a domain constant used in several places, declare it once as a named static const of the intended unsigned type and suffix it there.