pointer arithmetic

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • a

    pointer arithmetic

    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_cas t<unsigned short*>(0x8000) ;
    unsigned short offset = static_cast<uns igned short>(0x2);
    unsigned short *value = reinterpret_cas t<unsigned short*>(IO+offs et);

    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.


  • Kevin Goodsell

    #2
    Re: pointer arithmetic

    a wrote:
    [color=blue]
    > 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_cas t<unsigned short*>(0x8000) ;[/color]

    This is really a bad idea...
    [color=blue]
    > unsigned short offset = static_cast<uns igned short>(0x2);[/color]

    The cast in entirely unnecessary here. Never cast unless you absolutely
    have to.
    [color=blue]
    > unsigned short *value = reinterpret_cas t<unsigned short*>(IO+offs et);[/color]

    The cast is also unnecessary here.
    [color=blue]
    >
    > 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[/color]

    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(unsign ed int)

    or:

    p + n*2
    [color=blue]
    >
    > If IO is not a pointer, I get the result I expected.
    >
    > What is going on here?
    >[/color]

    Pointer arithmetic.

    -Kevin
    --
    My email address is valid, but changes periodically.
    To contact me please use the address from a recent posting.

    Comment

    • Ahti Legonkov

      #3
      Re: pointer arithmetic

      a wrote:[color=blue]
      > 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_cas t<unsigned short*>(0x8000) ;
      > unsigned short offset = static_cast<uns igned short>(0x2);[/color]

      // no cast needed here[color=blue]
      > unsigned short *value = reinterpret_cas t<unsigned short*>(IO+offs et);[/color]
      [color=blue]
      >
      > 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.[/color]


      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_cas t<int>(p) + 5*sizeof(unsign ed short);
      a = *reinterpret_ca st<unsigned short*>(i);

      --
      Ahti Legonkov

      Comment

      • Gavin Deane

        #4
        Re: pointer arithmetic

        Kevin Goodsell <usenet1.spamfr ee.fusion@never box.com> wrote in message news:<miW7b.740 8$PE6.5746@news read3.news.pas. earthlink.net>. ..[color=blue]
        > a wrote:
        >[color=green]
        > > 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_cas t<unsigned short*>(0x8000) ;[/color]
        >
        > This is really a bad idea...
        >[color=green]
        > > unsigned short offset = static_cast<uns igned short>(0x2);[/color]
        >
        > The cast in entirely unnecessary here. Never cast unless you absolutely
        > have to.
        >[color=green]
        > > unsigned short *value = reinterpret_cas t<unsigned short*>(IO+offs et);[/color]
        >
        > The cast is also unnecessary here.
        >[color=green]
        > >
        > > 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[/color]
        >
        > 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.[/color]

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

        <snip>

        GJD

        Comment

        • Ron Natalie

          #5
          Re: pointer arithmetic


          "Ahti Legonkov" <lego@127.0.0.1 > wrote in message news:3f6056b5$1 _1@news.estpak. ee...[color=blue]
          > a wrote:[/color]
          [color=blue]
          > 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.[/color]

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


          Comment

          • Kevin Goodsell

            #6
            Re: pointer arithmetic

            Gavin Deane wrote:
            [color=blue]
            > Kevin Goodsell <usenet1.spamfr ee.fusion@never box.com> wrote in message news:<miW7b.740 8$PE6.5746@news read3.news.pas. earthlink.net>. ..
            >[color=green]
            >>
            >>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.[/color]
            >
            >
            > Presumably, wherever you've written "unsigned int" (here and later)
            > you meant "unsigned short". Just in case the OP was confused.
            >[/color]

            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.

            Comment

            • a

              #7
              Re: pointer arithmetic


              "a" <agoff7@cox.net > wrote in message
              news:QPV7b.4888 7$Qy4.7224@fed1 read05...[color=blue]
              > 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_cas t<unsigned short*>(0x8000) ;
              > unsigned short offset = static_cast<uns igned short>(0x2);
              > unsigned short *value = reinterpret_cas t<unsigned short*>(IO+offs et);
              >
              > 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.
              >
              >[/color]

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


              Comment

              Working...