Versions Compared

Key

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

...

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

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

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

...

In this noncompliant code example, access by taking the address, casting the resulting pointer and dereferencing the result has undefined behavior, even if the cast uses a union type.

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

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

...

Type-punning is allowed provided the memory is accessed through the union type. This compliant solution returns the expected value.

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

...

In this noncompliant code example, an array of two shorts is treated as an integer and assigned an integer value. The resulting value of the two shorts is undefined.

Code Block
bgColor#FFCCCC
langc
short a[2];

a[0]=0x1111;
a[1]=0x1111;

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

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

...

This compliant solution uses a union type that includes a type compatible with the effective type of the object.

Code Block
bgColor#ccccff
langc
union {
  short a[2];
  int i;
} u;

u.a[0]=0x1111;
u.a[1]=0x1111;

u.i = 0x22222222;

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

...