According to subclause 6.2.7 of the C Standard [ISO/IEC 9899:2011],
All declarations that refer to the same object or function shall have compatible type; otherwise, the behavior is undefined.
(See also undefined behavior 14 of Annex J.)
Further, according to subclause 6.4.2.1,
Any identifiers that differ in a significant character are different identifiers. If two identifiers differ only in nonsignificant characters, the behavior is undefined.
(See also undefined behavior 30 of Annex J.)
Identifiers in mutually visible scopes must be deemed unique by the compiler to prevent confusion about which variable or function is being referenced. Implementations can allow additional non-unique nonunique characters to be appended to the end of identifiers, making the identifiers appear unique while actually being indistinguishable.
It is reasonable for scopes that are not visible to each other to have duplicate identifiers. For example, two functions can each have a local variable with the same name because their scopes cannot access each other. But a function's local variable names should be distinct from each other as well as from all static variables declared within the function's file (and from all included header files.)
To guarantee that identifiers are unique, you must first determine the number of significant characters recognized by ( the most restrictive ) compiler you are usingcompiler used must be determined. This assumption must be documented in the code.
...
- 63 significant initial characters in an internal identifier or a macro name. (each Each universal character name or extended source character is considered a single character.)
- 31 significant initial characters in an external identifier. (each Each universal character name specifying a short identifier of 0000FFFF or less is considered 6 characters, ; each
universal character name specifying a short identifier of 00010000 or more is considered 10 characters, ; and each extended source character, if any exist, is considered the same number of characters as the corresponding universal character name, if any.)
Restriction of the significance of an external name to fewer than 255 characters in the standard (considering each universal character name or extended source character as a single character) is an obsolescent feature that is a concession to existing implementations. ThereforeAs a result, it is not necessary to comply with this restriction , as long as your the identifiers are unique and your the assumptions concering concerning the number of significant characters is are documented.
...
Noncompliant Code Example
...
(Source Character Set)
On implementations that support only Assuming your compiler implements the minimum requirements for signficant significant characters required by the standard, the following examples are non-compliantthis code example is noncompliant because the first 31 characters of the external identifiers are identical:
| Code Block | ||||
|---|---|---|---|---|
| ||||
extern int *global_symbol_definition_lookup_table_a[100]; extern int *global_symbol_definition_lookup_table_b[100]; |
Compliant Solution (Source Character Set)
In a compliant solution, the significant characters in each identifier must differ:The external indentifiers in this example are not unique because the first 31 characters are identical.
| Code Block | ||||
|---|---|---|---|---|
| ||||
extern int \U00010401\U00010401\U00010401\U00010401[100]*a_global_symbol_definition_lookup_table; extern int \U00010401\U00010401\U00010401\U00010402[100]; *b_global_symbol_definition_lookup_table; |
Noncompliant Code Example (Universal Character Names)
In this noncompliant code In this example, both external identifiers consist of four universal characters, but only character names. Because the first three characters are unique. In practice, this means that both identifiers are referring to universal character names of each identifier are identical, both identify the same integer array .
Compliant Solution
In the compliant solution, the signficant characters in each identifier vary.on implementations that support only the minimum requirements for significant characters required by the standard:
| Code Block | ||||
|---|---|---|---|---|
| ||||
extern int a_global_symbol_definition_lookup_table[100]*\U00010401\U00010401\U00010401\U00010401; extern int b_global_symbol_definition_lookup_table[100]; *\U00010401\U00010401\U00010401\U00010402; |
Compliant Solution (Universal Character Names)
For portabilityAgain, assuming a minimally compliant implementation, the first three universal characters character name combinations used in an identifier must be unique.:
| Code Block | ||||
|---|---|---|---|---|
| ||||
extern int *\U00010401\U00010401\U00010401\U00010401[100]; extern int *\U00010402\U00010401\U00010401\U00010401[100]; |
Risk Assessment
Non-unique Nonunique identifiers can lead to abnormal program termination and , denial-of-service attacks, or unintended information disclosure.
Rule | Severity | Likelihood | Detectable |
|---|
Repairable | Priority | Level |
|---|
DCL23-C | Medium | Unlikely | Yes | Yes | P6 | L2 |
Automated Detection
Tool | Version | Checker | Description |
|---|---|---|---|
| Astrée |
1 (low)
1 (unlikely)
3 (low)
P3
L3
| Supported indirectly via MISRA C:2012 Rules 5.1, 5.2, 5.3, 5.4 and 5.5. | ||||||||
| Axivion Bauhaus Suite |
| CertC-DCL23 | |||||||
| CodeSonar |
| LANG.ID.ND.EXT LANG.ID.NU.EXT LANG.STRUCT.DECL.MGT | Non-distinct identifiers: external names Non-unique identifiers: external name Global variable declared with different types | ||||||
| Compass/ROSE | Can detect some violations of this rule but cannot flag violations involving universal names | ||||||||
| Helix QAC |
| C0627, C0776, C0777, C0778, C0779, C0789, C0791, C0793 | |||||||
| Klocwork |
| MISRA.IDENT.DISTINCT.C99.2012 | |||||||
| LDRA tool suite |
| 17 D | Fully implemented | ||||||
| PC-lint Plus |
| 621 | Fully supported | ||||||
| Polyspace Bug Finder |
| Checks for:
Rec. fully covered. | |||||||
| RuleChecker |
| Supported indirectly via MISRA C:2012 Rules 5.1, 5.2, 5.3, 5.4 and 5.5. | |||||||
| SonarQube C/C++ Plugin |
| IdentifierLongerThan31 |
Related Vulnerabilities
Search for Examples of vulnerabilities resulting from the violation of this rule can be found on the CERTwebsite CERT website.
References
Related Guidelines
| ISO/IEC TR 24772:2013 | Choice of Clear Names [NAI] Identifier Name Reuse [YOW] |
| MISRA C:2012 | Rule 5.1 (required) |
Bibliography
| [ISO/IEC 9899:2011] | Subclause 6.2.7, "Compatible Type and Composite Type" |
...
.4.1, |
...
"Keywords" |
...
Translation limits" \[[MISRA 04|AA. C References#MISRA 04]\] Rule 5.1