If a file-scope object or a function does not need to be visible outside of the file, it should be hidden by being declared as static
. This practice creates more modular code and limits pollution of the global name space.
Subclause Section 6.2.2 of C99 states that: \[of the C Standard [ISO/IEC 9899:1999|AA. C References#ISO/IEC 9899-1999]\]2011] states: Wiki Markup
If the declaration of a file scope identifier for an object or a function contains the storage-class specifier
static
, the identifier has internal linkage.
...
If the declaration of an identifier for an object has file scope and no storage-class specifier, its linkage is external.
If an object, such as a function, does not need to be visible outside the current scope, it should be hidden by being declared as static
. This helps create more modular code and may expose hidden assumptions about abstraction.
...
Noncompliant Code Example
This non-compliant noncompliant code example includes a helper()
function that is implicitly declared to have external linkage.:
Code Block | ||||
---|---|---|---|---|
| ||||
enum { MAX = 100 }; int helper(int i) { /* performPerform some computation based on i */ } int main(void) { intsize_t i; int out[MAX]; for (i = 0; i < MAX; i++) { out[i] = helper(i); } /* ... */ return 0; } |
Compliant Solution
This compliant solution declares helper()
to have internal linkage, thereby preventing objects external functions from other scopes from using it.:
Code Block | ||||
---|---|---|---|---|
| ||||
enum {MAX = 100}; static int helper(int i) { /* performPerform some computation based on i */ } int main(void) { intsize_t i; int out[MAX]; for (i = 0; i < MAX; i++) { out[i] = helper(i); } /* ... */ return 0; } |
Risk Assessment
Allowing too many objects to have external linkage can use up descriptive identifiers, leading to more complicated identifiers, violations of abstraction models, and possible name conflicts with libraries. If the compilation unit implements a data abstraction, it may also expose invocations of private functions from outside the abstraction.
Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
DCL15- |
C |
Low |
Unlikely |
Low | P3 | L3 |
Automated Detection
Tool |
---|
...
Version | Checker | Description | |||||||
---|---|---|---|---|---|---|---|---|---|
Astrée |
| global-object-scope | Fully checked | ||||||
Axivion Bauhaus Suite |
| CertC-DCL15 | |||||||
CodeSonar |
| LANG.STRUCT.SCOPE.FILE | Scope could be file static | ||||||
| CC2.DCL15 | Fully implemented | |||||||
Helix QAC |
| C1504, C1531 | |||||||
LDRA tool suite |
| 27 D | Fully implemented | ||||||
Parasoft C/C++test |
| CERT_C-DCL15-a | Objects or functions with external linkage shall be declared in a header file | ||||||
PC-lint Plus |
| 765 | Fully supported | ||||||
Polyspace Bug Finder |
| Checks for situations where function or object with external linkage is referenced in only one translation unit (rec. fully covered) | |||||||
RuleChecker |
| global-object-scope | Fully checked | ||||||
Splint |
|
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
...
Related Guidelines
SEI CERT C++ Coding Standard | VOID DCL15-CPP. Declare file-scope objects or functions that do not need external linkage in an unnamed namespace |
MISRA C:2012 | Rule 8.7 (advisory) |
Bibliography
ISO/IEC 9899:2011 | Subclause |
...
6.2.2, |
...
"Linkages |
...
of Identifiers" |
...
identifiers"DCL14-A. Do not make assumptions about the order of global variable initialization across translation units 02. Declarations and Initialization (DCL)