Versions Compared

Key

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

An object that has volatile-qualified type may be modified in ways unknown to the implementation or have other unknown side effects. It is possible to reference Referencing a volatile object by using a non-volatile value, but the resulting behavior lvalue is undefined . According to C99 Section behavior. The C Standard, 6.7.3, "Type qualifiers," Paragraph 5:4 paragraph 7 [ISO/IEC 9899:2024], states

If an attempt is made to refer to an object defined with a volatile-qualified type through use of an lvalue with non-volatile-qualified type, the behavior is undefined.

See undefined behavior 65.

Noncompliant Code Example

In this noncompliant code example, a volatile object is accessed through a non-volatile-qualified reference, resulting in undefined behavior:

Code Block
bgColor#FFcccc
langc
#include <stdio.h>
 
void func(void) {
  static volatile int **ipp;
  static int *ip;
  static volatile int i = 0;

  printf("i = %d.\n", i);

  ipp = &ip; /* May produce a warning diagnostic */
  ipp = (int**) &ip; /* Constraint violation; may produce a warning diagnostic */
  *ipp = &i; /* Valid */
  if (*ip != 0) { /* Valid */
    /* .

...

.. */
  }
}

The assignment ipp = &ip is not safe because it allows the valid code that follows to reference the value of the volatile object i through the non-volatile-qualified reference ip. In this example, the compiler may optimize out the entire if block because *ip != 0 must be false if the object to which ip points is not volatile.

Implementation Details

This example compiles without warning on Microsoft Visual Studio 2013 when compiled in C mode (/TC) but causes errors when compiled in C++ mode (/TP).

GCC 4.8.1 generates a warning but compiles successfully.

Compliant Solution

In this compliant solution, ip is declared volatile:

Code Block
bgColor#ccccff
langc
#include <stdio.h>

void func(void) {
  static volatile int **ipp;
  static volatile int *ip;
  static volatile int i = 0;

  printf("i = %d.\n", i);

  ipp = &ip;
  *ipp = &i;
  if (*ip != 0) {
    /* ... */
  }

}

Risk Assessment

Accessing an object with a volatile-qualified type through a reference with a non-volatile-qualified type is

This also applies to objects that behave as if they were defined with qualified types, such as an object at a memory-mapped input/output address.

...

Risk Assessment

Accessing a volatile object through a non-volatile reference results in undefined behavior.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

EXP32-C

1 (low)

3 (unlikely)

2 (medium)

P6

L2

Low

Likely

Medium

P6

L2

Automated Detection

Tool

Version

Checker

Description

Astrée
Include Page
Astrée_V
Astrée_V

pointer-qualifier-cast-volatile

pointer-qualifier-cast-volatile-implicit

Supported indirectly via MISRA C 2012 Rule 11.8
Axivion Bauhaus Suite

Include Page
Axivion Bauhaus Suite_V
Axivion Bauhaus Suite_V

CertC-EXP32Fully implemented
Clang
Include Page
Clang_V
Clang_V
-Wincompatible-pointer-types-discards-qualifiers
Compass/ROSE




Coverity
Include Page
Coverity_V
Coverity_V

MISRA C 2012 Rule 11.8

Implemented
Cppcheck Premium

Include Page
Cppcheck Premium_V
Cppcheck Premium_V

premium-cert-exp32-cPartially implemented
GCC
Include Page
GCC_V
GCC_V


Can detect violations of this rule when the -Wcast-qual flag is used

Helix QAC

Include Page
Helix QAC_V
Helix QAC_V

C0312, C0562, C0563, C0673, C0674Fully implemented
Klocwork
Include Page
Klocwork_V
Klocwork_V

CERT.EXPR.VOLATILE.ADDR
CERT.EXPR.VOLATILE.ADDR.PARAM
CERT.EXPR.VOLATILE.PTRPTR

Fully implemented
LDRA tool suite
Include Page
LDRA_V
LDRA_V

344 S

Partially implemented

Parasoft C/C++test
Include Page
Parasoft_V
Parasoft_V
CERT_C-EXP32-a

A cast shall not remove any 'const' or 'volatile' qualification from the type of a pointer or reference

Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C: Rule EXP32-C

Checks for cast to pointer that removes const or volatile qualification (rule fully covered)

RuleChecker

Include Page
RuleChecker_V
RuleChecker_V

pointer-qualifier-cast-volatile

pointer-qualifier-cast-volatile-implicit
Supported indirectly via MISRA C 2012 Rule 11.8

Related Vulnerabilities

Search for Examples of vulnerabilities resulting from the violation of this rule can be found on the CERT website.

References

Related Guidelines

Key here (explains table format and definitions)

Taxonomy

Taxonomy item

Relationship

ISO/IEC TR 24772:2013Pointer Casting and Pointer Type Changes [HFC]Prior to 2018-01-12: CERT: Unspecified Relationship
ISO/IEC TR 24772:2013Type System [IHN]Prior to 2018-01-12: CERT: Unspecified Relationship
MISRA C:2012Rule 11.8 (required)Prior to 2018-01-12: CERT: Unspecified Relationship
CERT CEXP55-CPP. Do not access a cv-qualified object through a cv-unqualified typePrior to 2018-01-12: CERT: Unspecified Relationship

Bibliography

[ISO/IEC 9899:2024]6.7.4, "Type Qualifiers"


...

Image Added Image Added Image Added Wiki Markup\[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]] Section 6.7.3, "Type qualifiers," and Section 6.5.16.1, "Simple assignment"