Discussion in 'C++' started by jignasuk@gmail.com, Jan 6, 2006.

1. ### Guest

Hello,

1 unsigned char ar[] = "AB";
2 unsigned int i = 0;
3 i = *(unsigned int *)ar;

How does it convert to unsigned int from unsigned char()? After
executing this three line I am getting 16961! How does this value
actually derived?

Thanks
JK

, Jan 6, 2006

2. ### Niels DybdahlGuest

> 1 unsigned char ar[] = "AB";
> 2 unsigned int i = 0;
> 3 i = *(unsigned int *)ar;
>
> How does it convert to unsigned int from unsigned char()? After
> executing this three line I am getting 16961! How does this value
> actually derived?

ar is the array containing "AB" with a trailing zero to terminate the
string.
It is first implicit converted to a pointer to the first character.
Then you typecast this pointer to a pointer which points to an unsigned int.
This means that the int starts at the same address as your string. If we
assume that in your implementation a char is 1 byte and an int is 4 bytes,
then the int will consists of the A, the B, the trailing zero and the byte
following that (which can have any value).
Depending upon your processor this is either with the most significant byte
at the first or last address.
An Intel processor will have it at the last address, so i will become
'A'+'B'*256+0*256*256+unspecified*256*256*256.
In ASCII 'A' is 65 and 'B' is 66 and apparently the unspecified value was
zero in this case, so you end up with 65+66*256=16961

Niels Dybdahl

Niels Dybdahl, Jan 6, 2006

3. ### Neelesh BodasGuest

wrote:
> Hello,
>
> 1 unsigned char ar[] = "AB";
> 2 unsigned int i = 0;
> 3 i = *(unsigned int *)ar;
>
> How does it convert to unsigned int from unsigned char()? After
> executing this three line I am getting 16961! How does this value
> actually derived?

As an aside from Neil's explanation -

Note that almost everything is implementation and architechture
dependent here, and not in the domain of std c++.
1. Size of char, int
2. Endianness of machine
3. casting from unsigned char* to int*

note that this type of typecasting has implementation defined effects
and hence is almost always guaranteed to be non-portable. Also, avoid
C-style casts. Use reinterpret_cast in this case (and C++ style casts
in general).

Neelesh Bodas, Jan 6, 2006

<> skrev i meddelandet
news:...
> Hello,
>
> 1 unsigned char ar[] = "AB";
> 2 unsigned int i = 0;
> 3 i = *(unsigned int *)ar;
>
> How does it convert to unsigned int from unsigned char()? After
> executing this three line I am getting 16961! How does this value
> actually derived?
>
> Thanks
> JK
>

Here's another view of what is happening here:

The name ar denotes an array of unsigned char. In some places, ar will
'decay' into a pointer to the first element of the array. Here the
type of the pointer would be 'unsigned char *'.

When you cast that pointer to another type, the compiler doesn't
convert it. It is YOU who say "the pointer is not a pointer to an
unsigned char, it is really a pointer to an unsigned int. Trust me, I
know what I am doing!". And the compiler is forced to trust you,
because that's the contract it works under.

If you then dereference the pointer, and it actually DOES point to an
unsigned int, you get the value of the int.

If you dereference the pointer, and it actually does NOT point to an
unsigned int, you have broken the contract with the compiler. It is
the free do do anything it feels like, perhaps show the value 16961.
Or crash, or format your harddisk.

Just don't lie to the compiler.

5. ### Tom WilsonGuest

16961 in Hex is 0x4241

If you look in a ascii chart, "A" is 0x41 "B" is 0x42.

Assuming you have a 4-byte unsigned int, the other 2 bytes were 0 at the
time, though don't count on it.

-Tom

"Bo Persson" <> wrote in message
news:...
>
> <> skrev i meddelandet
> news:...
>> Hello,
>>
>> 1 unsigned char ar[] = "AB";
>> 2 unsigned int i = 0;
>> 3 i = *(unsigned int *)ar;
>>
>> How does it convert to unsigned int from unsigned char()? After
>> executing this three line I am getting 16961! How does this value
>> actually derived?
>>
>> Thanks
>> JK
>>

>
> Here's another view of what is happening here:
>
> The name ar denotes an array of unsigned char. In some places, ar will
> 'decay' into a pointer to the first element of the array. Here the type of
> the pointer would be 'unsigned char *'.
>
> When you cast that pointer to another type, the compiler doesn't convert
> it. It is YOU who say "the pointer is not a pointer to an unsigned char,
> it is really a pointer to an unsigned int. Trust me, I know what I am
> doing!". And the compiler is forced to trust you, because that's the
> contract it works under.
>
> If you then dereference the pointer, and it actually DOES point to an
> unsigned int, you get the value of the int.
>
> If you dereference the pointer, and it actually does NOT point to an
> unsigned int, you have broken the contract with the compiler. It is the
> free do do anything it feels like, perhaps show the value 16961. Or crash,
>
>
> Just don't lie to the compiler.
>
>
>
>

Tom Wilson, Jan 10, 2006

"Tom Wilson" <> skrev i meddelandet
news:dq15cb\$lfa\$...
> 16961 in Hex is 0x4241
>
> If you look in a ascii chart, "A" is 0x41 "B" is 0x42.

Sure, that's an explanation for why this particular value might show
up.

> Assuming you have a 4-byte unsigned int, the other 2 bytes were 0
> at the time, though don't count on it.

The problem here is that formally we don't have any unsigned ints in
sight, just some unsigned chars. Then we tell the compiler that we
know better, that 'ar' really points to an unsigned char anyway.
"Honest, Gov. You can trust me. I would never lie to anyone!".

And we don't really have 4 bytes (if that is the size of an unsigned
int on this particular machine), we just have 3. So now we try to look
at the presumably first 4 bytes out of these 3. What happens? Poof?
16961? Something else?

Who knows, we have broken the contract. The compiler has the right to
sue us!

>
> -Tom
>
> "Bo Persson" <> wrote in message
> news:...
>>
>> <> skrev i meddelandet
>> news:...
>>> Hello,
>>>
>>> 1 unsigned char ar[] = "AB";
>>> 2 unsigned int i = 0;
>>> 3 i = *(unsigned int *)ar;
>>>
>>> How does it convert to unsigned int from unsigned char()? After
>>> executing this three line I am getting 16961! How does this value
>>> actually derived?
>>>
>>> Thanks
>>> JK
>>>

>>
>> Here's another view of what is happening here:
>>
>> The name ar denotes an array of unsigned char. In some places, ar
>> will 'decay' into a pointer to the first element of the array. Here
>> the type of the pointer would be 'unsigned char *'.
>>
>> When you cast that pointer to another type, the compiler doesn't
>> convert it. It is YOU who say "the pointer is not a pointer to an
>> unsigned char, it is really a pointer to an unsigned int. Trust me,
>> I know what I am doing!". And the compiler is forced to trust you,
>> because that's the contract it works under.
>>
>> If you then dereference the pointer, and it actually DOES point to
>> an unsigned int, you get the value of the int.
>>
>> If you dereference the pointer, and it actually does NOT point to
>> an unsigned int, you have broken the contract with the compiler. It
>> is the free do do anything it feels like, perhaps show the value
>> 16961. Or crash, or format your harddisk.
>>
>>
>> Just don't lie to the compiler.
>>
>>