Hello I have this example:
int main(){
int x = 300;
char* p = (char*)&x;
printf("%s\n", p);
printf("%d\n", *p);
}
The output:
,
44
Is it Undefined Behavior casting the address of x
to char*
as long as x
has a positive value that overflows a signed char
?
Why I got this output? ,
and 44
? I've tried to understand so I thought 300 % 256 = 44
is converted and assigned to p
so its character ASCII value is ,
on my implementation.
What do you think and recommend?
There is no UB here. Generally, going such things violates strict aliasing (causing UB), but there is an exception allowing you to use char
pointers to access any type.
300
is represented in memory as 4 bytes: 44 1 0 0
(assuming sizeof(int) == 4
, which is very common, and assuming little-endianness).
printf("%s\n", p);
interprets those 4 bytes as a C-string. You would get the same result by printing
const char str[4] = {44, 1, 0, 0}; // Same as `{',', '\1', '\0', '\0'}`
In theory, you could get UB if the byte representation of 300
didn't contain null bytes, as it would cause printf
to continue reading memory out of bounds of x
, looking for a null-terminator. But there are no real platforms where that's the case, so it should be safe.
And *p
accesses the first byte in the representation of x
, which is 44
.
If you were to try this code on a big-endian platform, you would get an empty string and a 0
respectively, since the byte representation of 300
would be 0 0 1 44
.
x
has a positive value that overflows asigned char
This isn't a problem.