Are there limits on what I can do to allocated memory?(standard-wise)
For example
#include <stdio.h>
#include <stdlib.h>
struct str{
long long a;
long b;
};
int main(void)
{
long *x = calloc(4,sizeof(long));
x[0] = 2;
x[3] = 7;
//is anything beyond here legal( if you would exclude possible illegal operations)
long long *y = x;
printf("%lld\n",y[0]);
y[0] = 2;
memset (x,0,16);
struct str *bar = x;
bar->b = 4;
printf("%lld\n",bar->a);
return 0;
}
To summarize:
Reading from y[0]
violates the strict aliasing rule. You use an lvalue of type long long
to read objects of effective type long
.
Assuming you omit that line; the next troublesome part is memset(x,0,16);
. This answer argues that memset
does not update the effective type. The standard is not clear.
Assuming that memset
leaves the effective type unchanged; the next issue is the read of bar->a
.
The C Standard is unclear on this too. Some people say that bar->a
implies (*bar).a
and this is a strict aliasing violation because we did not write a bar
object to the location first.
Others (including me) say that it is fine: the only lvalue used for access is bar->a
; that is an lvalue of type long long
, and it accesses an object of effective type long long
(the one written by y[0] = 2;
).
There is a C2X working group that is working on improving the specification of strict aliasing to clarify these issues.