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