Every declaration should be for a single variable, on its own line, with an explanatory comment about the role of the variable. Declaring multiple variables in a single declaration can cause confusion regarding the types of the variables and their initial values. If more than one variable is declared in a declaration, care must be taken that the type and initialized value of the variable are handled correctly.
Noncompliant Code Example
In this noncompliant code example, a programmer or code reviewer might mistakenly believe that the two variables src
and c
are declared as char *
. In fact, src
has a type of char *
, whereas c
has a type of char
.
Code Block | ||||
---|---|---|---|---|
| ||||
char *src = 0, c = 0; |
Compliant Solution
In this compliant solution, each variable is declared on a separate line:
Code Block | ||||
---|---|---|---|---|
| ||||
char *src; /* Source string */ char c; /* Character being tested */ |
Although this change has no effect on compilation, the programmer's intent is clearer.
Noncompliant Code Example
In this noncompliant code example, a programmer or code reviewer might mistakenly believe that both i
and j
have been initialized to 1. In fact, only j
has been initialized, and i
remains uninitialized.
Code Block | ||||
---|---|---|---|---|
| ||||
int i, j = 1; |
Compliant Solution
In this compliant solution, it is readily apparent that both i
and j
have been initialized to 1:
Code Block | ||||
---|---|---|---|---|
| ||||
int i = 1; int j = 1; |
Exceptions
Anchor | ||||
---|---|---|---|---|
|
for
statement, as shown in the following function:Code Block | ||||
---|---|---|---|---|
| ||||
#include <limits.h> /* For CHAR_BIT */ #include <stddef.h> /* For size_t */ extern size_t popcount(uintmax_t); #define PRECISION(umax_value) popcount(umax_value) size_t bitcount(size_t n) { const size_t limit = PRECISION(SIZE_MAX); size_t count = 0; for (size_t i = 0, j = 1; i < limit; ++i, j <<= 1) { if (n & j) ++count; } return count; } |
The PRECISION()
macro provides the correct precision for any integer type and is defined in INT35-C. Use correct integer precisions—see that rule for more information.
Anchor | ||||
---|---|---|---|---|
|
Code Block | ||||
---|---|---|---|---|
| ||||
int i, j, k; |
Risk Assessment
Declaring no more than one variable per declaration can make code easier to read and eliminate confusion.
Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
DCL04-C | Low | Unlikely | Low | P3 | L3 |
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Axivion Bauhaus Suite |
| CertC-DCL04 | |||||||
CodeSonar |
| LANG.STRUCT.DECL.ML | Multiple Declarations on Line | ||||||
| CC2.DCL04 | Fully implemented | |||||||
LDRA tool suite |
| 579 S | Fully implemented | ||||||
Parasoft C/C++test |
| CERT_C-DCL04-a | Each variable should be declared in a separate declaration statement | ||||||
PC-lint Plus |
| 9146 | Partially supported: exceptions not supported | ||||||
SonarQube C/C++ Plugin |
| SingleDeclarationPerStatement |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.