The C standard Standard allows an array variable to be declared both with a dimension index bound and with an initialization literal. The initialization literal also implies an array size, bound in the number of elements specified.
The size implied by an initialization literal is usually specified by the number of elements:,
Code Block |
---|
int array[] = {1, 2, 3}; /* 3-element array */
|
but one can it is also possible to use designators to initialize array elements in a non-contiguous noncontiguous fashion. section Subclause 6.7.8 "initialization"9, Example 12, of the C Standard [ISO/IEC 9899:2011] states:
Space can be "allocated" from both ends of an array by using a single designator:
Code Block int a[MAX] = { 1, 3, 5, 7, 9, [MAX-5] = 8, 6, 4, 2, 0 };
In the above, if
MAX
is greater than ten, there will be some zero-valued elements in the middle; if it is less than ten, some of the values provided by the first five initializers will be overridden by the second five.
C99 also The C Standard also dictates how array initialization is handled when the number of initialiation initialization elements does not equal the explicit array demsnionbound. From Section Subclause 6.7.8 "Initialiation", paragraph 219, paragraphs 21 and 22, state:
If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.
and paragraph 22:
If an array of unknown size is initialized, its size is determined by the largest indexed element with an explicit initializer. At The array type is completed at the end of its initializer list, the array no longer has incomplete type.
So while C Although compilers can compute the size of an array based on its array on the basis of its initialization list, we recommend explicitly specifying the size of the array explicitly. This provides a redundancy check, ensuring that the array's size is correct. It also enables compilers to emit warnings if the array's size is less than the size implied by the initialization.
Note that this advice recommendation does not apply (in all cases) to character arrays initialized with string literals, see STR36. See STR11-C. Do not specify the dimension bound of a character array initialized with a string literal for more information.
...
Noncompliant Code Example (Incorrect Size)
The following non-compliant code This noncompliant code example initializes an array of integers using an initialization with too many elements for the array.:
Code Block | ||||
---|---|---|---|---|
| ||||
int a[3] = {1, 2, 3, 4};
|
The size of the array a
is three3, although the size of the initialization is four4. The last element of the initialization (4
) is ignored. Most compilers will diagnose this error.
Implementation Details
This noncompliant code will generate example generates a warning in gcc
.
...
GCC. Microsoft Visual Studio generates a fatal diagnostic: error C2078: too many initializers
.
Noncompliant Code Example (Implicit Size)
The following non-compliant code initializes In this example, the compiler allocates an array of integers using an initialization with too many elements for the arrayfour integer elements and, because an array bound is not explicitly specified by the programmer, sets the array bound to 4
. However, if the initializer changes, the array bound may also change, causing unexpected results.
Code Block | ||||
---|---|---|---|---|
| ||||
int a[] = {1, 2, 3, 4};
|
The compiler will correctly assume an array size of 4. But if the initializer ever changes, the array size might change, cuasing unexpected results.
Compliant Solution
This compliant solution explicitly specifies the dimension of the array correctly.array bound:
Code Block | ||||
---|---|---|---|---|
| ||||
int a[4] = {1, 2, 3, 4};
|
Explicitly specifying the array bound, although it is implicitly defined by an initializer, allows a compiler or other static analysis tool to issue a diagnostic if these values do not agree.
Exceptions
ARR02-C-EX1: STR11-C. Do not specify the bound of a character array initialized with a string literal is a specific exception to this recommendation; it requires that the bound of a character array initialized with a string literal is unspecifiedThis is the preferred approach, because a programmer who changes the initializer size will be warned by the compiler that the array index should also change to accommodate the initializer.
Risk Assessment
Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
ARR02- |
C |
Medium |
Unlikely |
Low | P6 | L2 |
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Astrée |
| array-size-global | Partially checked | ||||||
Axivion Bauhaus Suite |
| CertC-ARR02 | Fully implemented | ||||||
Compass/ROSE | |||||||||
| CC2.ARR02 | Fully implemented | |||||||
Helix QAC |
| C0678, C0688, C3674, C3684 | |||||||
LDRA tool suite |
| 127 S | Fully implemented | ||||||
Parasoft C/C++test |
| CERT_C-ARR02-a | Explicitly specify array bounds in array declarations with initializers | ||||||
PC-lint Plus |
| 576 | Partially supported | ||||||
Polyspace Bug Finder |
| Checks for improper array initialization (rec, partially covered). | |||||||
PVS-Studio |
| V798 | |||||||
RuleChecker |
| array-size-global | Partially checked | ||||||
SonarQube C/C++ Plugin |
| S834 |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
Wiki Markup |
---|
\[[ISO/IEC 9899:1999|AA. C References#ISO/IEC 9899-1999]\] |
Related Guidelines
Key here (explains table format and definitions)
Taxonomy | Taxonomy item | Relationship |
---|---|---|
CERT C | CTR02-CPP. Explicitly specify array bounds, even if implicitly defined by an initializer | Prior to 2018-01-12: CERT: Unspecified Relationship |
CWE 2.11 | CWE-665, Incorrect or incomplete initialization | Prior to 2018-01-12: CERT: |
MISRA C:2012 | Rule 8.11 (advisory) | Prior to 2018-01-12: CERT: Unspecified Relationship |
MISRA C:2012 | Rule 9.5 (required) | Prior to 2018-01-12: CERT: Unspecified Relationship |
Bibliography
[ISO/IEC 9899:2011] | Subclause 6.7.9, "Initialization" |
...
ARR01-A. Do not apply the sizeof operator to a pointer when taking the size of an array 06. Arrays (ARR) ARR30-C. Guarantee that array indices are within the valid range