...
7. An object shall have its stored value accessed only by an lvalue expression that has one of
the following types: (78)——
- 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.
/78) The intent of this list is to specify those circumstances in which an object may or may not be aliased./
...
Noncompliant Code Example
In this 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 | ||
|---|---|---|
| ||
#include <stdio.h>
int main()
{
short a[2];
a[0]=0x1111;
a[1]=0x1111;
*(int *)a = 0x22222222; /* violation of aliasing rules */
printf("%x %x\n", a[0], a[1]);
return 0;
}
|
Optimized code produced by GCC 3.4.6.
.
| Code Block | ||
|---|---|---|
| ||
#include <stdio.h>
int main()
{
short a[2];
a[0]=0x1111;
a[1]=0x1111;
printf("%x %x\n", a[0], a[1]);
return 0;
}
|
Implementation Details
| Wiki Markup |
|---|
In the case above, the compiler may assume that no access through an integer pointer can change the array a, consisting of shorts. Thus, {{printf}} may be called with the original values of a\[0\] and a\[1\]. What really happens is up to the compiler and may change with architecture and optimization level. |
...
To disable optimizations based on alias-analysis for faulty legacy code, the option -fno-strict-aliasing can be used as a work-around. The option -Wstrict-aliasing (which is included in -Wall) warns about some - but not all - cases of violation of aliasing rules when -fstrict-aliasing is active.
When GCC 3.4.6 compiles this code with optimization, it yeilds an executable that behaves like the following code:
...
| Code Block | ||
|---|---|---|
| ||
#include <stdio.h>
int main()
{
short a[2];
a[0]=0x1111;
a[1]=0x1111;
printf("%x %x\n", a[0], a[1]);
return 0;
}
|
In other words, GCC 3.4.6 effectively removes the assignment.
Compliant Solution
To fix the code above, you can use a union instead of a cast.
...