return i++

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

    return i++

    Dear all,

    sorry, I always forget this thing:

    Is this foo:

    int foo(int i)
    {
    ++i;
    return i-1;
    }

    the same like this foo:

    int foo(int i)
    {
    return i++;
    }

    ? As I am alway scared using the ++ operators in compact forms, I'd better
    ask......

    Thanks,
    Patrick

    *************** *************

    Reply form:

    [ ] both foos are identical in the functionality and well defined
    [ ] keep your fingers away from "return i++"
    [ ] keep your fingers away from "return ++i"
    [ ] do not know

    Please mark the correct answers. More than one answer might be correct.


  • Victor Bazarov

    #2
    Re: return i++

    Patrick Kowalzick wrote:[color=blue]
    > sorry, I always forget this thing:
    >
    > Is this foo:
    >
    > int foo(int i)
    > {
    > ++i;
    > return i-1;
    > }
    >
    > the same like this foo:
    >
    > int foo(int i)
    > {
    > return i++;
    > }[/color]

    Yes. And it really is the same as

    int foo(int i)
    {
    return i;
    }
    [color=blue]
    >
    > ? As I am alway scared using the ++ operators in compact forms, I'd better
    > ask......
    >
    > Thanks,
    > Patrick
    >
    > *************** *************
    >
    > Reply form:
    >
    > [ ] both foos are identical in the functionality and well defined
    > [ ] keep your fingers away from "return i++"
    > [ ] keep your fingers away from "return ++i"
    > [ ] do not know
    >
    > Please mark the correct answers. More than one answer might be correct.[/color]

    You better mark the first one and the last one. Both answers are correct.

    V

    Comment

    • Patrick Kowalzick

      #3
      Re: return i++

      Dear Victor,
      [color=blue]
      > You better mark the first one and the last one. Both answers are correct.[/color]

      [x] both foos are identical in the functionality and well defined
      [ ] keep your fingers away from "return i++"
      [ ] keep your fingers away from "return ++i"
      [x] did not know

      Thanks ;),
      Patrick


      Comment

      • JKop

        #4
        Re: return i++


        int Blah()
        {
        int k = 5;

        return ++k;
        }


        The above function returns 6.

        --

        The below function returns 5.

        int Blah()
        {
        int k = 5;

        return k++;
        }

        --

        When you put ++ before the name: The object is incremented. The value of the
        expression is the object's value *after* the increment.

        When you putt ++ after the name: The value of the expression is the object's
        value *before* the increment. The object is incremented.


        Maybe the following will enlighten?:

        class Number
        {
        private:

        unsigned k;

        public:

        Number& operator++()
        {
        //This gets called when you do ++object
        //Note that it returns by reference

        k += 1;

        return *this;
        }

        Number operator++(int)
        {
        //This gets called when you do object++
        //Note that it returns by value

        //First we create a temporary, making a copy of the current object
        Number temp = *this;

        //Now we proceed with the increment
        k += 1;

        //But... we return the old value, ie. before the increment
        return temp;
        }
        };


        -JKop

        Comment

        • JKop

          #5
          Re: return i++

          [color=blue]
          > When you put ++ before the name: The object is incremented. The value
          > of the expression is the object's value *after* the increment.
          >
          > When you putt ++ after the name: The value of the expression is the
          > object's value *before* the increment. The object is incremented.[/color]


          Here's the simple way to remember it: Just read from left to right as
          normal:


          ++object;

          [increment], then [object];


          object++;

          [object], then [increment];


          Hopefully you're not Arabic!


          -JKop

          Comment

          • Patrick Kowalzick

            #6
            Re: return i++

            Dear JKop,

            thanks a lot for your explanations. Sorry that I did not express me right,
            but I know the thing about post- and pre-increment.

            The only problem I have, is to remember in which cases I run into undefined
            behaviour. So I'd better ask before ;). The compilers are not a good
            indicator here, because some may work, and others not (undefined).

            I was only *quite* sure that my code is fine, but not 100%.

            Thanks,
            Patrick


            Comment

            • Karl Heinz Buchegger

              #7
              Re: return i++

              Patrick Kowalzick wrote:[color=blue]
              >
              > Dear JKop,
              >
              > thanks a lot for your explanations. Sorry that I did not express me right,
              > but I know the thing about post- and pre-increment.
              >
              > The only problem I have, is to remember in which cases I run into undefined
              > behaviour. So I'd better ask before ;).[/color]

              In a nutshell:
              * make sure the variable that gets incremented is not the same variable
              assigned to.

              i = i++; // <- That's a no, no

              * don't increment the same variable more then once in a statement

              j = i++ + i++; // no, no
              foo( i++, i++ ); // no, no
              cout << i++ << i++; // no, no

              If you don't do any of the above you should be fairly safe
              (Did I miss some other common mistakes?)

              --
              Karl Heinz Buchegger
              kbuchegg@gascad .at

              Comment

              • Ron Natalie

                #8
                Re: return i++

                JKop wrote:
                [color=blue]
                >
                > When you put ++ before the name: The object is incremented. The value of the
                > expression is the object's value *after* the increment.
                >
                > When you putt ++ after the name: The value of the expression is the object's
                > value *before* the increment. The object is incremented.
                >[/color]

                Actually, in both cases:
                1. The object is incremented.
                2. The value returned is either the original or
                original value plus one.

                You can't make any statement about WHEN the increment occurs.


                Actually, I wouldn't have writen either ++k or k++.
                Since I don't really care to change k, just get a value
                one greater than it:

                return k+1;
                is MORE appropriate in my opinion.

                Comment

                • Victor Bazarov

                  #9
                  Re: return i++

                  Karl Heinz Buchegger wrote:[color=blue]
                  > Patrick Kowalzick wrote:
                  >[color=green]
                  >>Dear JKop,
                  >>
                  >>thanks a lot for your explanations. Sorry that I did not express me right,
                  >>but I know the thing about post- and pre-increment.
                  >>
                  >>The only problem I have, is to remember in which cases I run into undefined
                  >>behaviour. So I'd better ask before ;).[/color]
                  >
                  >
                  > In a nutshell:
                  > * make sure the variable that gets incremented is not the same variable
                  > assigned to.
                  >
                  > i = i++; // <- That's a no, no
                  >
                  > * don't increment the same variable more then once in a statement
                  >
                  > j = i++ + i++; // no, no
                  > foo( i++, i++ ); // no, no
                  > cout << i++ << i++; // no, no
                  >
                  > If you don't do any of the above you should be fairly safe
                  > (Did I miss some other common mistakes?)[/color]

                  Actually, variables is a bit too loose a requirement. It has to be
                  'object'. It is possible to increment the same object using different
                  variables:

                  int i = 42;
                  int& j = i;
                  i = j++; // same object, different variables

                  or even functions:

                  extern int i;

                  int foo() {
                  return i++;
                  }

                  int bar() {
                  i = foo(); // extremely obscured -- same object, and you don't
                  // even see the increment
                  }

                  V

                  Comment

                  • Andrey Tarasevich

                    #10
                    Re: return i++

                    Karl Heinz Buchegger wrote:[color=blue]
                    > ...
                    > In a nutshell:
                    > * make sure the variable that gets incremented is not the same variable
                    > assigned to.
                    >
                    > i = i++; // <- That's a no, no
                    >
                    > * don't increment the same variable more then once in a statement
                    >
                    > j = i++ + i++; // no, no
                    > foo( i++, i++ ); // no, no
                    > cout << i++ << i++; // no, no
                    >
                    > If you don't do any of the above you should be fairly safe
                    > (Did I miss some other common mistakes?)
                    > ...[/color]

                    You covered only the first part of the rule - multiple modifications
                    lead to UB. There's a second part as well - reading the old value for a
                    purpose other that calculating the new value leads to UB. For example

                    int i, j;
                    ...
                    j = i++ + i; // no, no

                    Of course, it would also be useful to explain the difference between
                    built-in and user-defined operators (and when undefined behavior turns
                    into unspecified behavior) but I'm afraid we'll need a rather large
                    nutshell for all this.

                    --
                    Best regards,
                    Andrey Tarasevich

                    Comment

                    • Patrick Kowalzick

                      #11
                      Re: return i++

                      Dear Victor, dear Karl Heinz,
                      [color=blue][color=green]
                      > > In a nutshell:
                      > > * make sure the variable that gets incremented is not the same variable
                      > > assigned to.
                      > >
                      > > i = i++; // <- That's a no, no
                      > >
                      > > * don't increment the same variable more then once in a statement
                      > >
                      > > j = i++ + i++; // no, no
                      > > foo( i++, i++ ); // no, no
                      > > cout << i++ << i++; // no, no[/color][/color]
                      [color=blue]
                      > Actually, variables is a bit too loose a requirement. It has to be
                      > 'object'. It is possible to increment the same object using different
                      > variables:
                      >
                      > int i = 42;
                      > int& j = i;
                      > i = j++; // same object, different variables
                      >
                      > or even functions:
                      >
                      > extern int i;
                      >
                      > int foo() {
                      > return i++;
                      > }
                      >
                      > int bar() {
                      > i = foo(); // extremely obscured -- same object, and you don't
                      > // even see the increment
                      > }[/color]

                      thanks. I try to burn it in my brain and will ask again in 6 month.

                      Regards,
                      Patrick


                      Comment

                      • Patrick Kowalzick

                        #12
                        Re: return i++


                        Dear Ron,
                        [color=blue]
                        > Actually, I wouldn't have writen either ++k or k++.
                        > Since I don't really care to change k, just get a value
                        > one greater than it:
                        >
                        > return k+1;
                        > is MORE appropriate in my opinion.[/color]

                        Normaly I´d agree, but it is a counter :) and should definitly be
                        incremented.

                        Regards,
                        Patrick


                        Comment

                        • Andrey Tarasevich

                          #13
                          Re: return i++

                          Victor Bazarov wrote:[color=blue]
                          > ...
                          > or even functions:
                          >
                          > extern int i;
                          >
                          > int foo() {
                          > return i++;
                          > }
                          >
                          > int bar() {
                          > i = foo(); // extremely obscured -- same object, and you don't
                          > // even see the increment
                          > }
                          > ...[/color]

                          Although it is worth mentioning that this case is very different from
                          the previous ones and the behavior is perfectly defined and specified,
                          since the modifications of 'i' are separated from each other by at least
                          one sequence point.

                          --
                          Best regards,
                          Andrey Tarasevich

                          Comment

                          • Victor Bazarov

                            #14
                            Re: return i++

                            Andrey Tarasevich wrote:[color=blue]
                            > Victor Bazarov wrote:
                            >[color=green]
                            >>...
                            >>or even functions:
                            >>
                            >> extern int i;
                            >>
                            >> int foo() {
                            >> return i++;
                            >> }
                            >>
                            >> int bar() {
                            >> i = foo(); // extremely obscured -- same object, and you don't
                            >> // even see the increment[/color][/color]

                            And I missed a return statement here...
                            [color=blue][color=green]
                            >> }
                            >>...[/color]
                            >
                            >
                            > Although it is worth mentioning that this case is very different from
                            > the previous ones and the behavior is perfectly defined and specified,
                            > since the modifications of 'i' are separated from each other by at least
                            > one sequence point.
                            >[/color]

                            You're absolutely right, I must have been thinking of this:

                            ------------------------ a.cc
                            extern int i;
                            void foo(int &j) {
                            j = i++;
                            }
                            ------------------------ b.cc
                            void foo(int&);
                            extern int i;
                            void bar() {
                            foo(i);
                            }

                            which is essentially the same as the first one, only the reference and
                            the object are separated from each other by a module border, while still
                            referring to the same object.

                            V

                            Comment

                            • Howard

                              #15
                              Re: return i++


                              "Patrick Kowalzick" <kowalzick@gmx. net> wrote in message
                              news:vqagd.9848 $1p.8289@nntpse rver.swip.net.. .[color=blue]
                              >
                              > Dear Ron,
                              >[color=green]
                              >> Actually, I wouldn't have writen either ++k or k++.
                              >> Since I don't really care to change k, just get a value
                              >> one greater than it:
                              >>
                              >> return k+1;
                              >> is MORE appropriate in my opinion.[/color]
                              >
                              > Normaly I4d agree, but it is a counter :) and should definitly be
                              > incremented.
                              >
                              > Regards,
                              > Patrick
                              >
                              >[/color]

                              If your original function (pasted below) is the way you actually have it in
                              code, the your "counter" isn't getting incremented, because you pass i in by
                              value, then increment the local copy of it. If you meant to change the
                              value that was passed in, make sure you pass it by reference (or pointer):

                              int foo(int i)
                              {
                              return i++;
                              }

                              should be:

                              int foo(int& i)
                              {
                              return i++;
                              }

                              -Howard



                              Comment

                              Working...