pointer arithmetic

A

a

I am having trouble understanding the results of the following code:

#include <iostream>
using namespace std;

int main(int argc, char* argv[])
{

unsigned short *IO = reinterpret_cast<unsigned short*>(0x8000);
unsigned short offset = static_cast<unsigned short>(0x2);
unsigned short *value = reinterpret_cast<unsigned short*>(IO+offset);

cout << "IO is " << hex << IO <<endl;
cout << "value is " << hex << value <<endl;

return 0;
}

The output for this case is: IO is 00008000, value is 00008004
I had expected value to be 00008002

If IO is not a pointer, I get the result I expected.

What is going on here?

Thanks to anyone with a helpful explanation.
 
K

Kevin Goodsell

a said:
I am having trouble understanding the results of the following code:

#include <iostream>
using namespace std;

int main(int argc, char* argv[])
{

unsigned short *IO = reinterpret_cast<unsigned short*>(0x8000);

This is really a bad idea...
unsigned short offset = static_cast<unsigned short>(0x2);

The cast in entirely unnecessary here. Never cast unless you absolutely
have to.
unsigned short *value = reinterpret_cast<unsigned short*>(IO+offset);

The cast is also unnecessary here.
cout << "IO is " << hex << IO <<endl;
cout << "value is " << hex << value <<endl;

return 0;
}

The output for this case is: IO is 00008000, value is 00008004
I had expected value to be 00008002

I get the same (after removing the unnecessary casts).

unsigned int is frequently 2 bytes on modern implementations. Because of
that, given a pointer to an unsigned int, adding 1 to that pointer has
to move it up 2 bytes to get to the next unsigned int. Likewise, adding
2 moves it up 4 bytes.

Basically, pointer arithmetic always works by translating:

p + n

(where p is a pointer and n is an integer) into:

p + n*sizeof(*p)

Of course, the second expression literally means something different to
the C++ language, but this is just a demonstration. The second is kind
of the compiler's interpretation. In your case, this translates to:

p + n*sizeof(unsigned int)

or:

p + n*2
If IO is not a pointer, I get the result I expected.

What is going on here?

Pointer arithmetic.

-Kevin
 
A

Ahti Legonkov

a said:
I am having trouble understanding the results of the following code:

#include <iostream>
using namespace std;

int main(int argc, char* argv[])
{

unsigned short *IO = reinterpret_cast<unsigned short*>(0x8000);
unsigned short offset = static_cast<unsigned short>(0x2);

// no cast needed here
unsigned short *value = reinterpret_cast<unsigned short*>(IO+offset);
cout << "IO is " << hex << IO <<endl;
cout << "value is " << hex << value <<endl;

return 0;
}

The output for this case is: IO is 00008000, value is 00008004
I had expected value to be 00008002

If IO is not a pointer, I get the result I expected.

What is going on here?

Thanks to anyone with a helpful explanation.


unsigned short *p = something;
unsigned short a;

// these two expressions are equivalent
a = p[5];
a = *(p+5);

The point is that when doing pointer arithmetic, the value that gets
added to the pointer value is multiplied by the size of the type pointed
to by the pointer. If it was different, the programmer would have to
worry about multiplying the offset by proper size and it would be really
inconvenient. Assuming that size of pointer == size of int the following
statement would be equivalent to the previous two:

int i = reinterpret_cast<int>(p) + 5*sizeof(unsigned short);
a = *reinterpret_cast<unsigned short*>(i);
 
G

Gavin Deane

Kevin Goodsell said:
a said:
I am having trouble understanding the results of the following code:

#include <iostream>
using namespace std;

int main(int argc, char* argv[])
{

unsigned short *IO = reinterpret_cast<unsigned short*>(0x8000);

This is really a bad idea...
unsigned short offset = static_cast<unsigned short>(0x2);

The cast in entirely unnecessary here. Never cast unless you absolutely
have to.
unsigned short *value = reinterpret_cast<unsigned short*>(IO+offset);

The cast is also unnecessary here.
cout << "IO is " << hex << IO <<endl;
cout << "value is " << hex << value <<endl;

return 0;
}

The output for this case is: IO is 00008000, value is 00008004
I had expected value to be 00008002

I get the same (after removing the unnecessary casts).

unsigned int is frequently 2 bytes on modern implementations. Because of
that, given a pointer to an unsigned int, adding 1 to that pointer has
to move it up 2 bytes to get to the next unsigned int. Likewise, adding
2 moves it up 4 bytes.

Presumably, wherever you've written "unsigned int" (here and later)
you meant "unsigned short". Just in case the OP was confused.

<snip>

GJD
 
R

Ron Natalie

Ahti Legonkov said:
The point is that when doing pointer arithmetic, the value that gets
added to the pointer value is multiplied by the size of the type pointed
to by the pointer.

Actually, it adds whatever it has to be to advance by that number of
objects. On word addressed machines adding 1 to a int pointer
literally adds 1 to the the internal value. On byte addressed machines
it does add sizeeof(int).
 
K

Kevin Goodsell

Gavin said:
Presumably, wherever you've written "unsigned int" (here and later)
you meant "unsigned short". Just in case the OP was confused.

Yeah... Check the posting time for an explanation. ;)

Yes, every occurrence of 'unsigned int' should have been 'unsigned short'.

-Kevin (shouldn't post after 2 a.m.)
 
A

a

a said:
I am having trouble understanding the results of the following code:

#include <iostream>
using namespace std;

int main(int argc, char* argv[])
{

unsigned short *IO = reinterpret_cast<unsigned short*>(0x8000);
unsigned short offset = static_cast<unsigned short>(0x2);
unsigned short *value = reinterpret_cast<unsigned short*>(IO+offset);

cout << "IO is " << hex << IO <<endl;
cout << "value is " << hex << value <<endl;

return 0;
}

The output for this case is: IO is 00008000, value is 00008004
I had expected value to be 00008002

If IO is not a pointer, I get the result I expected.

What is going on here?

Thanks to anyone with a helpful explanation.

Thanks to all for a nice explanation.

I do realize the casts were unneccesary (except the first, and it should be
noted that this is a piece of test code to a fixed address that will be
replaced with an OS function).
 

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

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top