c - Dereferencing this pointer gives me -46, but I am not sure why -
this program ran:
#include <stdio.h> int main() { int y = 1234; char *p = &y; int *j = &y; printf("%d " , *p); printf("%d" , *j); } i confused output. i'm seeing is:
-46 1234 i wrote program experiment , wasn't sure going output. expecting possibly 1 byte y.
what happening "behind-the-scenes" here? how dereferencing p give me -46?
update
pointed out other had explicit casting not cause ub.i not changing line char *p = &y char *p = (char *)&y not invalidating below answers.
there couple of issues code written.
first of all, invoking undefined behavior trying print numeric representation of char object using %d conversion specifier:
online c 2011 draft, §7.21.6.1, subclause 9:
if conversion specification invalid, behavior undefined.282) if argument not correct type corresponding conversion specification, behavior undefined.
yes, objects of type char promoted int when passed variadic functions; printf special, , if want output well-defined, type of argument , conversion specifier must match up. print numeric value of char %d or unsigned char argument %u, %o, or %x, must use hh length modifier part of conversion spec:
printf( "%hhd ", *p ); the second issue line
char *p = &y; is constraint violation - char * , int * not compatible types, , may have different sizes and/or representations2. thus, must explicitly cast source target type:
char *p = (char *) &y; the one exception rule occurs when 1 of operands void *; cast isn't necessary.
having said that, took code , added utility dumps address , contents of objects in program. here's y, p, , j on system (sles-10, gcc 4.1.2):
item address 00 01 02 03 ---- ------- -- -- -- -- y 0x7fff1a7e99cc d2 04 00 00 .... p 0x7fff1a7e99c0 cc 99 7e 1a ..~. 0x7fff1a7e99c4 ff 7f 00 00 .... j 0x7fff1a7e99b8 cc 99 7e 1a ..~. 0x7fff1a7e99bc ff 7f 00 00 .... i'm on x86 system, little-endian, stores multi-byte objects starting least-significant byte @ lowest address:
be: a+1 a+2 a+3 +----+----+----+----+ y: | 00 | 00 | 04 | d2 | +----+----+----+----+ le: a+3 a+2 a+1 on little-endian system, addressed byte least-significant byte, in case 0xd2 (210 unsigned, -46 signed).
in nutshell, you're printing signed, decimal representation of single byte.
as broader question, type of expression *p char , type of expression *j int; compiler goes type of expression. compiler keeps track of objects, expressions, , types translates source machine code. when sees expression *j, knows it's dealing integer value , generates machine code appropriately. when sees expression *p, knows it's dealing char value.
- admittedly, modern desktop systems know of use same representations pointer types, more oddball embedded or special-purpose platforms, may not true.
- § 6.2.5, subclause 28.
Comments
Post a Comment