Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

The

...

C

...

Standard allows

...

an

...

array

...

variable

...

to

...

be

...

declared

...

both

...

with

...

a

...

bound and

...

with

...

an

...

initialization

...

literal.

...

The

...

initialization

...

literal

...

also

...

implies

...

an

...

array

...

bound in

...

the

...

number

...

of

...

elements

...

specified.

...

The

...

size

...

implied

...

by

...

an

...

initialization

...

literal

...

is

...

usually

...

specified

...

by

...

the

...

number

...

of elements,

Code Block
 elements:

{code}
int array[] = {1, 2, 3}; /* 3-element array */

but one can use designators to initialize array elements in a non-contiguous fashion. section 6.7.8 "initialization":

{quote}
EXAMPLE 12 Space can be "allocated" from both ends of an array by using a single designator:
{code}

but it is also possible to use designators to initialize array elements in a noncontiguous fashion. Subclause 6.7.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.

The C Standard also dictates how array initialization is handled when the number of initialization elements does not equal the explicit array bound. Subclause 6.7.9, 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.
If an array of unknown size is initialized, its size is determined by the largest indexed element with an explicit initializer. The array type is completed at the end of its initializer list.

Although compilers can compute the size of an array on the basis of its initialization list, explicitly specifying the size of the array 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 recommendation does not apply (in all cases) to character arrays initialized with string literals. See STR11-C. Do not specify the bound of a character array initialized with a string literal for more information.

Noncompliant Code Example (Incorrect Size)

This noncompliant code example initializes an array of integers using an initialization with too many elements for the array:

Code Block
bgColor#FFCCCC
langc

{quote}

C99 also dictates how array initialization is handled when the number of initialiation elements does not equal the explicit array demsnion. From Section 6.7.8 "Initialiation", paragraph 21:

{quote}
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.
{quote}

and paragraph 22:

{quote}
If an array of unknown size is initialized, its size is determined by the largest indexed element with an explicit initializer. At the end of its initializer list, the array no longer has incomplete type.
{quote}

So while C can compute the size of an array based on its initialization list, we recommend specifying the size of the array explicitly. This provides a redundancy check 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 does not apply to character arrays initialized with string literals, see [STR36-C. Do not specify the dimension of a character array initialized with a string literal] for more information.

h2. Non-Compliant Code Example (Incorrect Size)

The following non-compliant code initializes an array of integers using an initialization with too many elements for the array.
{code:bgColor=#FFCCCC}
int a[3] = {1, 2, 3, 4};
{code}

The

...

size

...

of

...

the

...

array

...

a

...

is

...

3,

...

although

...

the

...

size

...

of

...

the

...

initialization

...

is

...

4.

...

The

...

last

...

element

...

of

...

the

...

initialization

...

(

...

4

...

)

...

is

...

ignored. Most compilers will diagnose this error.

Implementation Details

This noncompliant code example generates a warning in GCC. Microsoft Visual Studio generates a fatal diagnostic: error C2078: too many initializers.

Noncompliant Code Example (Implicit Size)

In this example, the compiler allocates an array of four 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
bgColor#FFCCCC
langc
.

This code will generate a warning in {{gcc}}.

h2. Non-Compliant Code Example (Implicit Size)

The following non-compliant code initializes an array of integers using an initialization with too many elements for the array.
{code:bgColor=#FFCCCC}
int a[] = {1, 2, 3, 4};
{code}
The compiler will correctly assume an array size of 4. But if the initializer ever changes, the array size might change, cuasing unexpected results.

h2. Compliant Solution

This compliant solution specifies the dimension of the array correctly.
{code:bgColor=#ccccff}

Compliant Solution

This compliant solution explicitly specifies the array bound:

Code Block
bgColor#ccccff
langc
int a[4] = {1, 2, 3, 4};
{code}
This 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.

h2. Risk Assessment

|| Recommendation || Severity || Likelihood || Remediation Cost || Priority || Level ||
| ARR02-A | medium | unlikely | low | {color:yellow}{*}P6{*}{color} | {color:yellow}{*}L2{*}{color} |

h3. Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the [CERT website|https://www.kb.cert.org/vulnotes/bymetric?searchview&query=FIELD+KEYWORDS+contains+ARR02-A].

h2. References

\[[ISO/IEC 9899:1999|AA. C References#ISO/IEC 9899-1999]\]


----
*[!CERT C Secure Coding Standard^button_arrow_left.png!|ARR01-A. Do not apply the sizeof operator to a pointer when taking the size of an array]**   *   *[!CERT C Secure Coding Standard^button_arrow_up.png!|06. Arrays (ARR)]**  *     *[!CERT C Secure Coding Standard^button_arrow_right.png!|ARR30-C. Guarantee that array indices are within the valid range]*

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 unspecified.

Risk Assessment

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

ARR02-C

Medium

Unlikely

Low

P6

L2

Automated Detection

Tool

Version

Checker

Description

Astrée
Include Page
Astrée_V
Astrée_V
array-size-globalPartially checked
Axivion Bauhaus Suite

Include Page
Axivion Bauhaus Suite_V
Axivion Bauhaus Suite_V

CertC-ARR02Fully implemented
Compass/ROSE




ECLAIR

Include Page
ECLAIR_V
ECLAIR_V

CC2.ARR02

Fully implemented

Helix QAC

Include Page
Helix QAC_V
Helix QAC_V

C0678, C0688, C3674, C3684


LDRA tool suite
Include Page
LDRA_V
LDRA_V

127 S
397 S
404 S

Fully  implemented

Parasoft C/C++test

Include Page
Parasoft_V
Parasoft_V

CERT_C-ARR02-a

Explicitly specify array bounds in array declarations with initializers

PC-lint Plus

Include Page
PC-lint Plus_V
PC-lint Plus_V

576

Partially supported

Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C: Rec. ARR02-C


Checks for improper array initialization (rec, partially covered).

PVS-Studio

Include Page
PVS-Studio_V
PVS-Studio_V

V798
RuleChecker
Include Page
RuleChecker_V
RuleChecker_V
array-size-globalPartially checked
SonarQube C/C++ Plugin
Include Page
SonarQube C/C++ Plugin_V
SonarQube C/C++ Plugin_V
S834

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Related Guidelines

Key here (explains table format and definitions)

Taxonomy

Taxonomy item

Relationship

CERT CCTR02-CPP. Explicitly specify array bounds, even if implicitly defined by an initializerPrior to 2018-01-12: CERT: Unspecified Relationship
CWE 2.11CWE-665, Incorrect or incomplete initializationPrior to 2018-01-12: CERT:
MISRA C:2012Rule 8.11 (advisory)Prior to 2018-01-12: CERT: Unspecified Relationship
MISRA C:2012Rule 9.5 (required)Prior to 2018-01-12: CERT: Unspecified Relationship

Bibliography

[ISO/IEC 9899:2011]Subclause 6.7.9, "Initialization"


...

Image Added Image Added Image Added