Could someone please explain?!

J

jignasuk

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
 
N

Niels Dybdahl

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
 
N

Neelesh Bodas

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).
 
B

Bo Persson

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.


Bo Persson
 
T

Tom Wilson

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 said:
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.


Bo Persson
 
B

Bo Persson

Tom Wilson said:
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!


Bo Persson


-Tom

Bo Persson said:
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.


Bo Persson
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,189
Latest member
CryptoTaxSoftware

Latest Threads

Top