Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Reworked an example, started reviewing but not completed.

...

An object shall have its stored value accessed only by an lvalue expression that has one of
the following types:

  • a type compatible with the effective type of the object,
  • a qualified version of a type compatible with the effective type of the object,
  • a type that is the signed or unsigned type corresponding to the effective type of the object,
  • a type that is the signed or unsigned type corresponding to a qualified version of the effective type of the object,
  • an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union), or
  • a character type.

...

In this noncompliant example, a diagnostic is required because an object of type float is incremented through a pointer to int, ip:an int *. Using the maximum units in last position is often done as a way to get the next representable value for a floating-point number. However, accessing an object through a pointer of incompatible types is undefined behavior.

Code Block
bgColor#FFCCCC
langc
#include <stdio.h>
 
void f(void) {
  if (sizeof(int) == sizeof(float)) {
    float f = 0.0f;
    int *ip = (int *)&f;
 
    printf("float is %f\n", f);
 
    (*ip)++;  /* Diagnostic required */
 
    printf("float is %f\n", f);
  }
}

...

In this compliant solution, the pointer to int, ip has been replaced by a pointer to float, fpthe standard C function nextafterf() is used to round towards the highest representable floating-point value:

Code Block
bgColor#ccccff
langc
#include <float.h>
#include <math.h>
#include <stdio.h>
 
void f(void) {
  if (sizeof(int) == sizeof(float)) {
    float f = 0.0f;
  f  float *fp = &f;
 
    printf("float is %f\n", f);
 
    (*fp)++;
 
  nextafterf(f, FLT_MAX);
  printf("float is %f\n", f);
  }
}

Noncompliant Code Example

The programmer in this This noncompliant code example is attempting attempts to read from a different union member than the one most recently written to, which is known as type-punning:.

Code Block
bgColor#FFCCCC
langc
union a_union {
  int i;
  double d;
};

int f(void) {
  union a_union t;
  int *ip;
  t.d = 3.0;
  ip = &t.i;
  return *ip;
}

However, instead of reading directly from of taking the address of the most-recently written member of the union member, it assigns a pointer, ip, to reference the integer value and returns the value referenced by the pointer. Unfortunately, this is a violation of the strict aliasing rules, and in this case, the , the code takes the address of a member that has not been written to. The compiler may determine that ip refers to some value other than the value stored by t.i and return a value other than the expected value.

...

Code Block
bgColor#FFCCCC
langc
union a_union {
  int i;
  double d;
};

int f(void) {
  double d = 3.0;
  return ((union a_union *) &d)->i;
}

...

Code Block
bgColor#ccccff
langc
union a_union {
  int i;
  double d;
};
          
int f(void) {
  union a_union t;
  t.d = 3.0;
  return t.i;
} 

...

Code Block
bgColor#FFCCCC
langc
#include <stdio.h>
 
void func(void) {
  short a[2];
  a[0]=0x1111;
  a[1]=0x1111;

  *(int *)a = 0x22222222;  /* Violation of aliasing rules */

  printf("%x %x\n", a[0], a[1]);

  /* ... */
}

When translating this code, an implementation can assume that no access through an integer pointer can change the array a, consisting of shorts. Consequently, printf() may be called with the original values of a[0] and a[1]. The actual behavior is implementation-defined and can change with optimization level.

Implementation Details

Recent versions of GCC turn on the option -fstrict-aliasing (which allows alias-based optimizations) by default with -O2. Some architectures then print "1111 1111" as a result. Without optimization, the executable generates the expected output "2222 2222."

...

Tool

Version

Checker

Description

PRQA QA-C
Include Page
PRQA_V
PRQA_V

0310
3305

Partially implemented

Related Vulnerabilities

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

Related Guidelines

ISO/IEC TS 17961Accessing an object through a pointer to an incompatible type [ptrcomp]

...

[Acton 2006]"Understanding Strict Aliasing"
GCC Known Bugs"C Bugs, Aliasing Issues while Casting to Incompatible Types"
GCC Manual 
[ISO/IEC 9899:2011]Subclause 6.5, "Expressions"
[Walfridsson 2003]Aliasing, Pointer Casts and GCC 3.3

 

...