Reputation: 1
Just i was testing my understanding of pointers, while doing so i did this,
Okay this is what i think.
All pointers to any type hold addresses, right?
Say i declare
char *a, b = 'f';
a = &b ;
So when i try to access content of b that is &b, through a pointer to type char.which is okay.
But, What if i store address of int data type in a pointer of char type(although i get warning: assignment from incompatible pointer type [-Wincompatible-pointer-types], i'm not doing wrong, right?.i'm still storing address of some memory.)
int main(){
// int type of one byte
int a, i ;
char *b;
for(i = -256 ;i < 257; ++i){
a = i;
b = &a;
printf("for i = %d, value stored in first byte of a = %d\n",i ,*b);
}
return 0;
}
now i thought that it will be allowed to read only first byte of 4 bytes allocated to a because i'm accessing through a pointer to a char type, i was expecting to store values up to 255, beyond this will be kind of overflow.
but it happened something different i could only store 127 to -128 whao!!.Did you see it a type int of size one byte.You can run code to see.
Now assume that int type is of size one byte
when a = 256, value read is 0, which is expected, because 0001 0000 0000 it will read only first byte.
Output is predictable until we reach a = 127, which is stored as 0111 1111 (which is positive value from type int perspective)
when a = 128, output is -128 , which is stored 1000 0000 (which is indeed -128)
similarly other outputs can be explained
So output can be explained by assuming that int type is of size one byte, why did printf do that instead of throwing error.
So what exactly did printf do here?
Thank you excellencies ;)
Upvotes: 2
Views: 173
Reputation: 123548
But, What if i store address of int data type in a pointer of char type(although i get warning: assignment from incompatible pointer type [-Wincompatible-pointer-types], i'm not doing wrong, right?.i'm still storing address of some memory.)
Yeah, you’re doing something wrong, which is why you get the warning.
Pointer type matters for two reasons:
Pointer arithmetic is done in terms of objects, not bytes. If p
is a char *
and its value is the address of a char
object (say 0x1000
), then p + 1
evaluates to the address of the next char
object (0x1001
). If p
is an int *
and its value is the address of a 4-byte int
object (0x2000
), the p + 1
evaluates to the address of the next 4-byte int
object (0x2004
).
Like other types, different pointer types may have different sizes and representations. An int *
may have a different representation from a char *
. On most modern systems like x86 and x86_64 they’re the same, but there are some older or oddball architectures where that’s not the case.
So output can be explained by assuming that int type is of size one byte, why did printf do that instead of throwing error.
The issue isn't with printf
, the issue is that you're encountering signed integer overflow when you attempt to assign 128
to *b
, since on your system plain char
occupies the range [-128..127]
. Unfortunately, the behavior on signed integer overflow is undefined - there's no requirement that your implementation handle it in any particular way. Most implementations that I'm aware of don't try to handle it at all - you just get an unexpected value. Given that there are multiple signed integer representations, and given that many implementations rely on that undefined behavior to perform certain optimizations, you could get pretty much any result.
Upvotes: 0
Reputation: 399949
Your system uses signed characters, which is totally normal.
You seem to assume/expect char
to be unsigned
, which is not always true. It is either signed or unsigned, but that depends on the implementation.
Upvotes: 5