...
In this noncompliant example, a diagnostic is required because an object of type float is incremented through a pointer to int
, ip
.:
Code Block | ||||
---|---|---|---|---|
| ||||
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
, fp
.:
Code Block | ||||
---|---|---|---|---|
| ||||
void f(void) { if (sizeof(int) == sizeof(float)) { float f = 0.0f; float *fp = &f; printf("float is %f\n", f); (*fp)++; printf("float is %f\n", f); } } |
...
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 | ||||
---|---|---|---|---|
| ||||
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 | ||||
---|---|---|---|---|
| ||||
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 | ||||
---|---|---|---|---|
| ||||
union a_union { int i; double d; }; int f() { a_union t; t.d = 3.0; return t.i; } |
...
This compliant solution uses a union
type that includes a type compatible with the effective type of the object.:
Code Block | ||||
---|---|---|---|---|
| ||||
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]); |
...
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
PRQA QA-C |
| 0310 | Partially implemented |
Related Guidelines
ISO/IEC TS 17961 (Draft) | Accessing an object through a pointer to an incompatible type [ptrcomp] |
Bibliography
[Acton 2006] | "Understanding Strict Aliasing" |
GCC Known Bugs | "C Bugs, Aliasing Issues while Casting to Incompatible Types" |
GCC Manual | |
[ISO/IEC 9899:2011] | Section 6.5, "Expressions" |
[Walfridsson 2003] | Aliasing, Pointer Casts and GCC 3.3 |
...