incrementing void *

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • subramanian100in@yahoo.com, India

    #1

    incrementing void *

    I saw this question from www.brainbench.com

    void *ptr;
    myStruct myArray[10];

    ptr = myArray;

    Which of the following is the correct way to increment the variable
    "ptr"?
    Choice 1 ptr = ptr + sizeof(ptr);
    Choice 2 increment(ptr);
    Choice 3 ++(int*)ptr;
    Choice 4 ptr = ptr + sizeof(myArray) ;
    Choice 5 ptr = ptr + sizeof(myStruct );

    THEIR Correct Answer given in this site is: ptr = ptr +
    sizeof(myStruct );

    But my answer is ++(int*)ptr. The reason is that ptr being void *, we
    cannot add any number to it. It must be cast to a valid object before
    incrementing.

    Which is correct ?

  • Ian Collins

    #2
    Re: incrementing void *

    subramanian100i n@yahoo.com, India wrote:
    I saw this question from www.brainbench.com
    >
    void *ptr;
    myStruct myArray[10];
    >
    ptr = myArray;
    >
    Which of the following is the correct way to increment the variable
    "ptr"?
    Choice 1 ptr = ptr + sizeof(ptr);
    Choice 2 increment(ptr);
    Choice 3 ++(int*)ptr;
    Choice 4 ptr = ptr + sizeof(myArray) ;
    Choice 5 ptr = ptr + sizeof(myStruct );
    >
    THEIR Correct Answer given in this site is: ptr = ptr +
    sizeof(myStruct );
    >
    But my answer is ++(int*)ptr. The reason is that ptr being void *, we
    cannot add any number to it. It must be cast to a valid object before
    incrementing.
    >
    (int*)ptr isn't an lvalue, so you can not increment it.
    Which is correct ?
    >
    ptr = ptr + sizeof(myStruct );

    --
    Ian Collins.

    Comment

    • P.J. Plauger

      #3
      Re: incrementing void *

      "Ian Collins" <ian-news@hotmail.co mwrote in message
      news:55c7h5F23m 2gqU12@mid.indi vidual.net...
      subramanian100i n@yahoo.com, India wrote:
      >I saw this question from www.brainbench.com
      >>
      >void *ptr;
      >myStruct myArray[10];
      >>
      >ptr = myArray;
      >>
      >Which of the following is the correct way to increment the variable
      >"ptr"?
      >Choice 1 ptr = ptr + sizeof(ptr);
      >Choice 2 increment(ptr);
      >Choice 3 ++(int*)ptr;
      >Choice 4 ptr = ptr + sizeof(myArray) ;
      >Choice 5 ptr = ptr + sizeof(myStruct );
      >>
      >THEIR Correct Answer given in this site is: ptr = ptr +
      >sizeof(myStruc t);
      >>
      >But my answer is ++(int*)ptr. The reason is that ptr being void *, we
      >cannot add any number to it. It must be cast to a valid object before
      >incrementing .
      >>
      (int*)ptr isn't an lvalue, so you can not increment it.
      Nonsense. There are dangers in incrementing (int *)ptr if
      myStruct is not on at least as strong a storage boundary as
      int (or if you're on a machine where even ten MyStruct are
      smaller than a single int). But lvaleness has nothing to do
      with it.
      >Which is correct ?
      ptr = ptr + sizeof(myStruct );
      Nonsense. You can't add anything to a void *.

      The posed question doesn't answer the burning question,
      "increment by what?". One possible sensible interpretation
      is to undo the implicit void cast and write:

      ptr = ++((myStruct *)ptr);

      Yet another is:

      ptr = ++((myStruct[10] *)ptr);

      These at least have the virtue of being well defined. But
      then so does:

      ptr = ++(char *)ptr);

      so the problem is at least ambiguous. And we still don't
      know what the function increment does.

      I predict a very long, unimportant thread.

      P.J. Plauger
      Dinkumware, Ltd.



      Comment

      • subramanian100in@yahoo.com, India

        #4
        Re: incrementing void *

        I myself know that ++(int *)ptr is not correct. But among the five
        choices given and if one choice has to be selected,
        only ++(int *)ptr can be incremented because only in this case, object
        size is known for doing the incrementation.

        Comment

        • Ian Collins

          #5
          Re: incrementing void *

          P.J. Plauger wrote:
          >>
          >>(int*)ptr isn't an lvalue, so you can not increment it.
          >
          >
          Nonsense. There are dangers in incrementing (int *)ptr if
          myStruct is not on at least as strong a storage boundary as
          int (or if you're on a machine where even ten MyStruct are
          smaller than a single int). But lvaleness has nothing to do
          with it.
          >
          Oops, I appear to have posted complete bollocks. Sorry.

          --
          Ian Collins.

          Comment

          • santosh

            #6
            Re: incrementing void *

            subramanian100i n@yahoo.com, India wrote:
            I saw this question from www.brainbench.com
            >
            void *ptr;
            myStruct myArray[10];
            >
            ptr = myArray;
            >
            Which of the following is the correct way to increment the variable
            "ptr"?
            Choice 1 ptr = ptr + sizeof(ptr);
            Choice 2 increment(ptr);
            Choice 3 ++(int*)ptr;
            Choice 4 ptr = ptr + sizeof(myArray) ;
            Choice 5 ptr = ptr + sizeof(myStruct );
            None. The closest is choice two, depending on what the function
            exactly does.
            THEIR Correct Answer given in this site is: ptr = ptr +
            sizeof(myStruct );
            You cannot do any arithmetic on void pointers.
            But my answer is ++(int*)ptr. The reason is that ptr being void *, we
            cannot add any number to it. It must be cast to a valid object before
            incrementing.
            But why a cast to int *? The more likely cast would be to myStruct *
            or myStruct[10] *. Also you can use a cast to unsigned char * to
            access the bytes of the array myArray.

            Comment

            • santosh

              #7
              Re: incrementing void *

              subramanian100i n@yahoo.com, India wrote:
              I myself know that ++(int *)ptr is not correct.
              It's not that it is not correct. It's just likely to be wrong.
              But among the five
              choices given and if one choice has to be selected,
              only ++(int *)ptr can be incremented because only in this case, object
              size is known for doing the incrementation.
              It would work only if myStruct's alignment requirements are only as
              strict as for an int, something that's unlikely unless myStruct
              happens to be an obfuscatory typedef for int.

              I myself, if forced, would've chosen choice two.

              Comment

              • santosh

                #8
                Re: incrementing void *

                P.J. Plauger wrote:
                "Ian Collins" <ian-news@hotmail.co mwrote in message
                news:55c7h5F23m 2gqU12@mid.indi vidual.net...
                >
                subramanian100i n@yahoo.com, India wrote:
                I saw this question from www.brainbench.com
                >
                void *ptr;
                myStruct myArray[10];
                >
                ptr = myArray;
                >
                Which of the following is the correct way to increment the variable
                "ptr"?
                Choice 1 ptr = ptr + sizeof(ptr);
                Choice 2 increment(ptr);
                Choice 3 ++(int*)ptr;
                Choice 4 ptr = ptr + sizeof(myArray) ;
                Choice 5 ptr = ptr + sizeof(myStruct );
                >
                THEIR Correct Answer given in this site is: ptr = ptr +
                sizeof(myStruct );
                >
                But my answer is ++(int*)ptr. The reason is that ptr being void *, we
                cannot add any number to it. It must be cast to a valid object before
                incrementing.
                [ ... ]
                Which is correct ?
                >
                ptr = ptr + sizeof(myStruct );
                >
                Nonsense. You can't add anything to a void *.
                >
                The posed question doesn't answer the burning question,
                "increment by what?". One possible sensible interpretation
                is to undo the implicit void cast and write:
                >
                ptr = ++((myStruct *)ptr);
                Shouldn't this be:

                ptr = ((myStruct *) ptr) + 1;

                and similarly for the others?

                Comment

                • Keith Thompson

                  #9
                  Re: incrementing void *

                  "P.J. Plauger" <pjp@dinkumware .comwrites:
                  "Ian Collins" <ian-news@hotmail.co mwrote in message
                  news:55c7h5F23m 2gqU12@mid.indi vidual.net...
                  >subramanian100i n@yahoo.com, India wrote:
                  >>I saw this question from www.brainbench.com
                  >>>
                  >>void *ptr;
                  >>myStruct myArray[10];
                  >>>
                  >>ptr = myArray;
                  >>>
                  >>Which of the following is the correct way to increment the variable
                  >>"ptr"?
                  >>Choice 1 ptr = ptr + sizeof(ptr);
                  >>Choice 2 increment(ptr);
                  >>Choice 3 ++(int*)ptr;
                  >>Choice 4 ptr = ptr + sizeof(myArray) ;
                  >>Choice 5 ptr = ptr + sizeof(myStruct );
                  >>>
                  >>THEIR Correct Answer given in this site is: ptr = ptr +
                  >>sizeof(myStru ct);
                  >>>
                  >>But my answer is ++(int*)ptr. The reason is that ptr being void *, we
                  >>cannot add any number to it. It must be cast to a valid object before
                  >>incrementin g.
                  >>>
                  >(int*)ptr isn't an lvalue, so you can not increment it.
                  >
                  Nonsense. There are dangers in incrementing (int *)ptr if
                  myStruct is not on at least as strong a storage boundary as
                  int (or if you're on a machine where even ten MyStruct are
                  smaller than a single int). But lvaleness has nothing to do
                  with it.
                  Um, are you sure you're not thinking of the C++ rules?

                  The result of a cast is not an lvalue, and the argument to "++" must
                  be an lvalue, so Choice 3 is a constraint violation. (Both gcc and
                  Sun's C compiler complain about it; that doesn't prove anything, but
                  it does bolster my confidence.) You can add 1 to it, but you can't
                  increment it with "++".

                  (Choices 1, 4, and 5 are also constraint violations, since addition
                  isn't defined for void*. Choice 2 *could* be correct if "increment"
                  were a carefully crafted macro, but I don't think that's the intent.)
                  >>Which is correct ?
                  >
                  >ptr = ptr + sizeof(myStruct );
                  >
                  Nonsense. You can't add anything to a void *.
                  >
                  The posed question doesn't answer the burning question,
                  "increment by what?". One possible sensible interpretation
                  is to undo the implicit void cast and write:
                  >
                  ptr = ++((myStruct *)ptr);
                  >
                  Yet another is:
                  >
                  ptr = ++((myStruct[10] *)ptr);
                  >
                  These at least have the virtue of being well defined. But
                  then so does:
                  >
                  ptr = ++(char *)ptr);
                  >
                  so the problem is at least ambiguous. And we still don't
                  know what the function increment does.
                  All three of these, if a cast yielded an lvalue, would modify ptr
                  twice between sequence points and therefore invoke undefined behavior
                  (<PICKY>and the last one has a missing parenthesis</PICKY>). Changing
                  "++" to "1 + " should fix that.

                  I understand that *some* casts in C++ yield lvalues, but I don't know
                  the rules. Perhaps the question on brainbench.com was actually about
                  C++? Or maybe it was just wrong.

                  I'm hesitant to take the risk of disagreeing with P.J. Plauger, but
                  either I'm right or I'm about to learn something.

                  --
                  Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                  San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
                  "We must do something. This is something. Therefore, we must do this."
                  -- Antony Jay and Jonathan Lynn, "Yes Minister"

                  Comment

                  • Keith Thompson

                    #10
                    Re: incrementing void *

                    "santosh" <santosh.k83@gm ail.comwrites:
                    subramanian100i n@yahoo.com, India wrote:
                    >I saw this question from www.brainbench.com
                    >>
                    >void *ptr;
                    >myStruct myArray[10];
                    >>
                    >ptr = myArray;
                    >>
                    >Which of the following is the correct way to increment the variable
                    >"ptr"?
                    >Choice 1 ptr = ptr + sizeof(ptr);
                    >Choice 2 increment(ptr);
                    >Choice 3 ++(int*)ptr;
                    >Choice 4 ptr = ptr + sizeof(myArray) ;
                    >Choice 5 ptr = ptr + sizeof(myStruct );
                    >
                    None. The closest is choice two, depending on what the function
                    exactly does.
                    [...]

                    If increment is a function, it can't modify ptr. It could be a macro,
                    though.

                    --
                    Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                    San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
                    "We must do something. This is something. Therefore, we must do this."
                    -- Antony Jay and Jonathan Lynn, "Yes Minister"

                    Comment

                    • Servé Laurijssen

                      #11
                      Re: incrementing void *


                      "Keith Thompson" <kst-u@mib.orgwrote in message
                      news:lnabymbtmd .fsf@nuthaus.mi b.org...
                      >Nonsense. There are dangers in incrementing (int *)ptr if
                      >myStruct is not on at least as strong a storage boundary as
                      >int (or if you're on a machine where even ten MyStruct are
                      >smaller than a single int). But lvaleness has nothing to do
                      >with it.
                      >
                      Um, are you sure you're not thinking of the C++ rules?
                      >
                      The result of a cast is not an lvalue, and the argument to "++" must
                      be an lvalue, so Choice 3 is a constraint violation. (Both gcc and
                      Sun's C compiler complain about it; that doesn't prove anything, but
                      it does bolster my confidence.) You can add 1 to it, but you can't
                      increment it with "++".
                      it doesnt work in C++ either. +1 would be best



                      Comment

                      • Richard Tobin

                        #12
                        Re: incrementing void *

                        In article <vdadnY7AAcVaaG 3YnZ2dnUVZ_tijn Z2d@giganews.co m>,
                        P.J. Plauger <pjp@dinkumware .comwrote:
                        >>But my answer is ++(int*)ptr. The reason is that ptr being void *, we
                        >>cannot add any number to it. It must be cast to a valid object before
                        >>incrementin g.
                        >(int*)ptr isn't an lvalue, so you can not increment it.
                        >Nonsense. There are dangers in incrementing (int *)ptr if
                        >myStruct is not on at least as strong a storage boundary as
                        >int (or if you're on a machine where even ten MyStruct are
                        >smaller than a single int). But lvaleness has nothing to do
                        >with it.
                        You can add 1 to (int *)ptr, but you can't assign the result to
                        it, because (int *)ptr is indeed not an lvalue (since some draft
                        of C89).

                        You can do ptr = (int *)ptr + 1 which converts the value back
                        to void * before assigning it to plain uncast ptr.

                        -- Richard
                        >The posed question doesn't answer the burning question,
                        >"increment by what?". One possible sensible interpretation
                        >is to undo the implicit void cast and write:
                        >
                        ptr = ++((myStruct *)ptr);
                        I think you're temporarily confused. You can't apply ++ to cast
                        expressions in standard C.

                        -- Richard
                        --
                        "Considerat ion shall be given to the need for as many as 32 characters
                        in some alphabets" - X3.4, 1963.

                        Comment

                        • Richard Tobin

                          #13
                          Re: incrementing void *

                          In article <lnabymbtmd.fsf @nuthaus.mib.or g>,
                          Keith Thompson <kst-u@mib.orgwrote:
                          >The result of a cast is not an lvalue, and the argument to "++" must
                          >be an lvalue, so Choice 3 is a constraint violation. (Both gcc and
                          >Sun's C compiler complain about it; that doesn't prove anything, but
                          >it does bolster my confidence.)
                          gcc has traditionally allowed this as an extension; gcc 4.0 reports

                          warning: target of assignment not really an lvalue; this will be a
                          hard error in the future

                          -- Richard
                          --
                          "Considerat ion shall be given to the need for as many as 32 characters
                          in some alphabets" - X3.4, 1963.

                          Comment

                          • santosh

                            #14
                            Re: incrementing void *

                            Keith Thompson wrote:
                            "santosh" <santosh.k83@gm ail.comwrites:
                            subramanian100i n@yahoo.com, India wrote:
                            I saw this question from www.brainbench.com
                            >
                            void *ptr;
                            myStruct myArray[10];
                            >
                            ptr = myArray;
                            >
                            Which of the following is the correct way to increment the variable
                            "ptr"?
                            Choice 1 ptr = ptr + sizeof(ptr);
                            Choice 2 increment(ptr);
                            Choice 3 ++(int*)ptr;
                            Choice 4 ptr = ptr + sizeof(myArray) ;
                            Choice 5 ptr = ptr + sizeof(myStruct );
                            None. The closest is choice two, depending on what the function
                            exactly does.
                            [...]
                            >
                            If increment is a function, it can't modify ptr. It could be a macro,
                            though.
                            Yes, careless of me. It's unlikely to be a macro though, given that
                            it's in lower case.

                            Comment

                            • ais523

                              #15
                              Re: incrementing void *

                              On Mar 9, 11:02 am, "santosh" <santosh....@gm ail.comwrote:
                              Keith Thompson wrote:
                              "santosh" <santosh....@gm ail.comwrites:
                              subramanian10.. .@yahoo.com, India wrote:
                              >I saw this question fromwww.brainbe nch.com
                              >
                              >void *ptr;
                              >myStruct myArray[10];
                              >
                              >ptr = myArray;
                              >
                              >Which of the following is the correct way to increment the variable
                              >"ptr"?
                              >Choice 1 ptr = ptr + sizeof(ptr);
                              >Choice 2 increment(ptr);
                              >Choice 3 ++(int*)ptr;
                              >Choice 4 ptr = ptr + sizeof(myArray) ;
                              >Choice 5 ptr = ptr + sizeof(myStruct );
                              >
                              None. The closest is choice two, depending on what the function
                              exactly does.
                              [...]
                              >
                              If increment is a function, it can't modify ptr. It could be a macro,
                              though.
                              >
                              Yes, careless of me. It's unlikely to be a macro though, given that
                              it's in lower case
                              There are several lowercase macros in the standard; stdin (as long as
                              <stdio.his #included) is one I can think of off the top of my head,
                              and I know there are others. Anyway, the problem here is that the
                              answer to 'what is the correct way to increment a void* variable' is
                              'you don't increment void* variables'; incrementing a void* variable
                              can't sensibly be defined because void is an incomplete type. The
                              (incorrect, because sizeof(void) can't be taken) "ptr = (char*)ptr +
                              sizeof(void);" would come nearest to what the question is asking. On
                              the other hand, the answer to "what is the correct way to cause ptr to
                              point at the element of myArray after the one it's currently pointing
                              at" would be ptr=1+(myStruct *)ptr, assuming that myStruct is a typedef
                              for a user-defined struct type (which would seem plausible from the
                              name, but this hasn't been stated). Out of the choices actually given,
                              2 is the only one that stands a chance of being correct (if increment
                              is a carefully-defined macro); 1, 4, and 5 all try to do arithmetic on
                              void* (impossible because void is incomplete), and 3 isn't legal in C
                              (but is an extension I've seen on more than one compiler, and which I
                              would use in some cases if it were portable, obviously using myStruct*
                              rather than int*).
                              --
                              ais523

                              Comment

                              Working...