Reputation: 23699
I don't know why the following code works fine, without gcc
errors (-fstrict-aliasing -Wstrict-aliasing=1
).
#include <stdio.h>
int
main(void)
{
char n = 42;
char *p = &n;
int *q = (int *)p;
*q = 10;
printf("%d|%d\n", *p, *q);
return 0;
}
If I follow the strict aliasing rule:
n1570, § 6.5 Expressions
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.
But *q
does not have a type compatible with *p
, either a qualified version, either a signed or unsigned type corresponding, either a character type.
So, why is it allowed?
Upvotes: 2
Views: 238
Reputation: 25752
It is not allowed. The part of the Standard you posted shows through what types are you allowed to alias objects.
The fact that the code compiled doesn't mean it is correct. You are having three problems with the code that make it the program exhibit undefined behavior.
First is that you assigned a char pointer to an int pointer. Standard doesn't enforce their alignment and representation, so the resulting pointer is not valid.
int *q = (int *)p;
Then you interpreted the char n
object as an integer, violating strict aliasing.( Note the quote from the Standard in your question ).
*q;
Finally you wrote an int
into the memory of the char object (char n
), which causes an overflow because the size of an int
is always larger than size of a char
.
*q = 10;
Upvotes: 3