CertC-DCL15

Declare file-scope objects or functions that do not need external linkage as static

Required inputs: IR

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 6.2.2 of the C Standard [ ISO/IEC 9899:2011] states:

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.

and

If the declaration of an identifier for an object has file scope and no storage-class specifier, its linkage is external.

Noncompliant Code Example

This noncompliant code example includes a helper() function that is implicitly declared to have external linkage:

enum { MAX = 100 };

int helper(int i) {
  /* Perform some computation based on i */
}

int main(void) {
  size_t i;
  int out[MAX];

  for (i = 0; i < MAX; i++) {
    out[i] = helper(i);
  }

  /* ... */

}
Compliant Solution

This compliant solution declares helper() to have internal linkage, thereby preventing external functions from using it:

enum {MAX = 100};

static int helper(int i) {
  /* Perform some computation based on i */
}

int main(void) {
  size_t i;
  int out[MAX];

  for (i = 0; i < MAX; i++) {
    out[i] = helper(i);
  }

  /* ... */

}
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
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)
Rule 8.8 (required)
Bibliography
ISO/IEC 9899:2011 Subclause 6.2.2, "Linkages of Identifiers"
Excerpt from SEI CERT C Coding Standard: Rules for Developing Safe, Reliable, and Secure Systems (2016 Edition) and SEI CERT C Coding Standard [https://cmu-sei.github.io/secure-coding-standards/sei-cert-c-coding-standard/recommendations/declarations-and-initialization-dcl/dcl15-c], Copyright (C) 1995-2026 Carnegie Mellon University. See section 9.4. "3rd-Party Licenses" in the documentation for full details.

Possible Messages

Key

Text

Severity

Disabled

function_file_static

{} can be declared static in primary file.

None

False

var_file_static

{} can be declared static in primary file.

None

False

Options

allow_moving_to_other_primary_file

allow_moving_to_other_primary_file : bool = False

When a variable is only used in a single file X, but currently implemented in a different file Y, this controls whether the check suggests to move it into X and make it static there.
 

exclude_dllexport

exclude_dllexport : bool = True

If true, no suggestions will be produced to make functions marked as dllexport or dllimport static in a primary file.
 

exclude_function_locals

exclude_function_locals : bool = True

If true, variables that could even be function-local are not reported.
 

exclude_undefined

exclude_undefined : bool = True

Whether only-declared symbols should be reported as well.
 

template_args_can_be_static

template_args_can_be_static : bool = False

Whether functions whose address is used as template argument can be made static (some compilers, like Microsoft's, do not allow it then).