(unsigned int) vs. (unsigned char)

0 views
Skip to first unread message

Gurjeet Singh

unread,
Aug 3, 2005, 10:37:34 PM8/3/05
to compg...@googlegroups.com
Hi all,

I am perplexed by the following code!!! I think it has something
to do with sign-extension, but I need a complete explanation.

I came across this problem when I wanted to convert an ip-address
onto a printable string. The struct has an array of chars, and as we
know, each component of the address can range between 0 to 255. When I
typecasted the char array's elements to (unsigned int), I got a
negative number if the value was greater than 127; but if I used
(unsigned char) I could print those values properly.

I have reduced the problem statement. Here, why 'i' prints as -128
and 'j' as 128. In other words, why is (unsigned int) not working
whereas (unsigned char) is doing the expected job.

<snip>
#include <stdio.h>

int main()
{
signed char c;
unsigned int i, j;

c = 128;
i = (unsigned int)c;
j = (unsigned char)c;

printf( "%d : %d : %u : %d : %d : %d : %d \n",
c, (unsigned int)c, (unsigned int)c, (unsigned char)c,
i, j, (unsigned int)128 );

return 0;
}
</snip>

if you see the values of c,i and j in hex, here's what you will see.
c: 0x80
i: 0xffffff80
j: 0x80

So, I think it has something to do with sign extension. But what
exactly??? and why is the compiler doing it?

Thanks,
Gurjeet.

PS: I have tried it on VC++6 and cygwin. and the results are the same.

Dipendra Ganotra

unread,
Aug 8, 2005, 6:08:28 PM8/8/05
to compg...@googlegroups.com
Hi Sardar,

here is what i found.

74: c = 128;
004010F8 mov byte ptr [ebp-4],80h
75: i = (unsigned int)c;
004010FC movsx eax,byte ptr [ebp-4]
00401100 mov dword ptr [ebp-8],eax
76: j = (unsigned char)c;
00401103 mov ecx,dword ptr [ebp-4]
00401106 and ecx,0FFh
0040110C mov dword ptr [ebp-0Ch],ecx
77:
78: printf( "%d : %d : %u : %d : %d : %d : %d \n",
79: c, (unsigned int)c, (unsigned int)c, (unsignedchar)c,
80: i, j, (unsigned int)128 );
0040110F push 80h
00401114 mov edx,dword ptr [ebp-0Ch]
00401117 push edx
00401118 mov eax,dword ptr [ebp-8]
0040111B push eax
0040111C mov ecx,dword ptr [ebp-4]
0040111F and ecx,0FFh
00401125 push ecx
00401126 movsx edx,byte ptr [ebp-4]
0040112A push edx
0040112B movsx eax,byte ptr [ebp-4]
0040112F push eax
00401130 movsx ecx,byte ptr [ebp-4]
00401134 push ecx
00401135 push offset string "%d : %d : %u : %d : %d : %d : %d"...
(00420f84)
0040113A call printf (00401220)
0040113F add esp,20h


If you look at this, when ever we use (unsigned int) if copy only a
byte, but for (unsigned char) it copy a dword. So in case of (unsigned
int) the rest of the 3 bytes remains uninitializied. Right now i dont
have reasoning for this, but might help to.
I tried initializing i to 0. but still doesn't work.

tell me what u think of this.

dhanashri

unread,
Aug 9, 2005, 5:04:53 AM8/9/05
to compg...@googlegroups.com

 Since size of (int) > sizeof(char) this type of casting will always create a problem.
Here is the link which gives the close approach to solve the problem:
http://www.ozzu.com/ftopic1723.html

--Dhanashri.
Reply all
Reply to author
Forward
0 new messages