Versions Compared

Key

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

Section Subclause 6.5.2.5 of the the C Standard [ISO/IEC 9899:1999 (C99) standard 2011] defines a compound literal (CL) as:

A postfix A postfix expression that consists of a parenthesized type name followed by a brace-enclosed list of initializers. . . . The value of a of the compound literal is that of an unnamed object initiated by the initializer list.

The storage for this object is either static (if the CL compound literal occurs at file scope) or automatic (if the CL compound literal occurs at block scope (6.5.2.5.6).

E.g., after the execution of the following line, contained in some arbitrary function:

, and the storage duration is associated with its immediate enclosing block. For example, in the function

Code Block
void func(void) {
  int *ip
Code Block

int *i = (int[4]){1,2,3,4};

...

 

...

 /* ... */
}

following initialization, the int pointer ip contains the address of an unnamed object of type int[4], allocated on the stack. Once func returns, any attempts to access this object will produce undefined behavior.

Note "i" would contain the address of an unnamed object of type "int \[4\]", allocated on the stack.It should be noted that only one object is created per CL -- even compound literal—even if the CL compound literal appears in a loop and has dynamic initializers (6.5.2.5.16). This can lead to incorrect use, as demonstrated below..

This recommendation is a specific instance of DCL30-C. Declare objects with appropriate storage durations.

Noncompliant Code Example

Wiki MarkupIn the following example, an array of pointers is filled with what appear to addresses of distinct INT_STRUCT objects, one for each integer in the range \In this noncompliant code example, the programmer mistakenly assumes that the elements of the ints array of the pointer to int_struct are assigned the addresses of distinct int_struct objects, one for each integer in the range [0, MAX_INTS - 1\]:

Code Block
bgColor#FFCCCC
borderStylelangsolidc

#include <stdio.h>

typedef struct INTint_STRUCTstruct {
  int x;
} INTint_STRUCTstruct;

#define MAX_INTS 10

int main(int argc,char **argvvoid){
  intsize_t i;
  INTint_STRUCTstruct *ints[MAX_INTS];

  for (i = 0;i<MAX i < MAX_INTS; i++) {
    ints[i] = &(INTint_STRUCTstruct){i};
  }

  for (i = 0;i<MAX i < MAX_INTS; i++) {
    printf("%d\n", ints[i]->x);
  }
 
  return 0;
}

However, only one INTint_STRUCT struct object is actually created. At each iteration of the first loop, the "x" member of this object is set equal to the current value of the loop counter , "i". Therefore, after just before the first loop terminates, the value of the "x" member is MAX_INTS - 1.

During the print loop, this value is printed MAX_INTS times because every pointer in the "ints" array is set to point to the (single) INT_STRUCT object.

Because the storage duration of the compound literal is associated with the for loop that contains it, dereferencing ints in the second loop results in undefined behavior 9 (Annex J of the C Standard).

Even if the region of memory that contained the compound literal is not written to between loops, the print loop will display the value MAX_INTS - 1 for MAX_INTS lines. This is contrary to the intuitive expected result, which is that the integers 0 through MAX_INTS - 1 would be printed in order.

Compliant Solution

This compliant solution uses an array of structures rather than an array of pointers. That way, an actual copy of each INTint_STRUCT struct (rather than a pointer to the object) is stored.

Code Block
bgColor#CCCCFF
borderStylesolid
langc

#include <stdio.h>

typedef struct INTint_STRUCTstruct {
  int x;
} INTint_STRUCTstruct;

#define MAX_INTS 10

int main(int argc,char** argvvoid){
  intsize_t i;
  INTint_STRUCTstruct ints[MAX_INTS];

  for (i = 0;i<MAX i < MAX_INTS; i++) {
    ints[i] = (INTint_STRUCTstruct){i};
  }

  for (i = 0;i<MAX i < MAX_INTS; i++) {
    printf("%d\n", ints[i].x);
  }
 
  return 0;
}

Risk Assessment

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

DCL21-C

low

Low

unlikely

Unlikely

medium

Medium

P2

L3

References

...

Automated Detection

Tool

Version

Checker

Description

Axivion Bauhaus Suite

Include Page
Axivion Bauhaus Suite_V
Axivion Bauhaus Suite_V

CertC-DCL21
Helix QAC

Include Page
Helix QAC_V
Helix QAC_V

C1054, C3217

Bibliography

[ISO/IEC 9899:2011]Subclause

...

6.5.2.5

...

, "Compound

...

Literals"


...

Image Added Image Added Image Added)