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 nonvolatile value, but the resulting behavior non-volatile lvalue is undefined behavior. The C Standard, Section 6.7.3 4 paragraph 7 [ISO/IEC 9899:20112024], 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 also undefined behavior 65 in Appendix J of the C Standard.)

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; /* producesMay warningsproduce ina modernwarning compilersdiagnostic */
  ipp = (int**) &ip; /* constraintConstraint violation, also produces warnings; may produce a warning diagnostic */
  *ipp = &i; /* validValid */
  if (*ip != 0) { /* validValid */
    /* ... */
  }
}

The assignment ipp = &ip is unsafe not safe because it would allow 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 it is not possible that i *ip != 0 if i 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++ .NET mode (2003) and on MS Visual Studio 2005.

This example does not compile on MS Visual Studio 2008. The error message is

Code Block
error C2440: '=' : cannot convert from 'int **' to 'volatile int **'

/TP).

GCC 4.8.1 generates a warning but compiles Versions 3.2.2 and 4.1.3 of the GCC compiler generate a warning but compile 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

Casting away volatile allows access to Accessing an object with a volatile-qualified type through a nonvolatile reference. This can result in undefined and perhaps unintended program reference with a non-volatile-qualified type is undefined behavior.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

EXP32-C

low

Low

likely

Likely

medium

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

Fully implemented

PRQA QA-C Include PagePRQA_VPRQA_V0312

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
Fully implemented

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 C++ Secure Coding StandardEXP32-CPP. Do not access a volatile object through a non-volatile reference

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:
2011
2024]
Section
6.7.
3
4, "Type Qualifiers"

...


...

Image Modified Image Modified Image Modified