pointer arithmetic

Discussion in 'C++' started by a, Sep 11, 2003.

  1. a

    a Guest

    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.
    a, Sep 11, 2003
    #1
    1. Advertising

  2. a wrote:

    > 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
    --
    My email address is valid, but changes periodically.
    To contact me please use the address from a recent posting.
    Kevin Goodsell, Sep 11, 2003
    #2
    1. Advertising

  3. a wrote:
    > 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);

    --
    Ahti Legonkov
    Ahti Legonkov, Sep 11, 2003
    #3
  4. a

    Gavin Deane Guest

    Kevin Goodsell <> wrote in message news:<miW7b.7408$>...
    > a wrote:
    >
    > > 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
    Gavin Deane, Sep 11, 2003
    #4
  5. a

    Ron Natalie Guest

    "Ahti Legonkov" <lego@127.0.0.1> wrote in message news:3f6056b5$...
    > a wrote:


    > 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).
    Ron Natalie, Sep 11, 2003
    #5
  6. Gavin Deane wrote:

    > Kevin Goodsell <> wrote in message news:<miW7b.7408$>...
    >
    >>
    >>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.
    >


    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.)
    --
    My email address is valid, but changes periodically.
    To contact me please use the address from a recent posting.
    Kevin Goodsell, Sep 11, 2003
    #6
  7. a

    a Guest

    "a" <> wrote in message
    news:QPV7b.48887$Qy4.7224@fed1read05...
    > 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).
    a, Sep 12, 2003
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Marc Schellens

    Iterator/pointer arithmetic

    Marc Schellens, Dec 5, 2003, in forum: C++
    Replies:
    15
    Views:
    846
    tom_usenet
    Dec 8, 2003
  2. dan

    Pointer arithmetic

    dan, Jan 6, 2004, in forum: C++
    Replies:
    1
    Views:
    362
    Jeff Schwab
    Jan 6, 2004
  3. ceo
    Replies:
    8
    Views:
    357
    Pete Becker
    Mar 10, 2005
  4. Replies:
    21
    Views:
    1,137
    Richard Herring
    Apr 27, 2005
  5. joshc
    Replies:
    5
    Views:
    556
    Keith Thompson
    Mar 31, 2005
Loading...

Share This Page