Find The Bug

Discussion in 'C++' started by David Rasmussen, Jan 15, 2004.

  1. I have this code:

    #include <iostream>

    using namespace std;

    #define DeclareEnumTricks(T) \
    inline T& operator++(T& e) \
    { \
    e = T(e+1); \
    return e; \
    } \
    \
    inline T operator++(T& e, int) \
    { \
    T old = e; \
    e = T(e+1); \
    return old;\
    } \
    \
    inline T& operator--(T& e) \
    { \
    e = T(e-1); \
    return e; \
    } \
    \
    inline T operator--(T& e, int) \
    { \
    T old = e; \
    e = T(e-1); \
    return old; \
    } \
    \
    inline T end(T) \
    { \
    return T##_end; \
    } \
    \
    inline T begin(T) \
    { \
    return T##_begin; \
    }

    enum Piece {none,pawn,knight,bishop,rook,queen,king,
    Piece_begin = pawn, Piece_end = king + 1};
    DeclareEnumTricks(Piece)

    int main()
    {
    Piece p = none;
    cout << p << " " << p++ << " " << ++p << endl;
    }

    The output from g++ and several other compilers is _not_

    0 0 2

    as expected. In g++ it is

    2 1 1

    Is there a bug in the code, or in the compilers?

    /David
    David Rasmussen, Jan 15, 2004
    #1
    1. Advertising

  2. David Rasmussen

    Fao, Sean Guest

    > cout << p << " " << p++ << " " << ++p << endl;
    > Is there a bug in the code, or in the compilers?


    In the FAQ.
    Fao, Sean, Jan 15, 2004
    #2
    1. Advertising

  3. Fao, Sean wrote:
    >> cout << p << " " << p++ << " " << ++p << endl;
    >>Is there a bug in the code, or in the compilers?

    >
    >
    > In the FAQ.


    Thanks. I've looked, but I can't find anything relevant. Could be more
    specific?

    /David
    David Rasmussen, Jan 15, 2004
    #3
  4. David Rasmussen

    Sumit Rajan Guest

    "David Rasmussen" <> wrote in message
    news:bu6u3g$sv6$-c.dk...
    > I have this code:
    >
    > #include <iostream>
    >
    > using namespace std;
    >
    > #define DeclareEnumTricks(T) \
    > inline T& operator++(T& e) \
    > { \
    > e = T(e+1); \
    > return e; \
    > } \
    > \
    > inline T operator++(T& e, int) \
    > { \
    > T old = e; \
    > e = T(e+1); \
    > return old;\
    > } \
    > \
    > inline T& operator--(T& e) \
    > { \
    > e = T(e-1); \
    > return e; \
    > } \
    > \
    > inline T operator--(T& e, int) \
    > { \
    > T old = e; \
    > e = T(e-1); \
    > return old; \
    > } \
    > \
    > inline T end(T) \
    > { \
    > return T##_end; \
    > } \
    > \
    > inline T begin(T) \
    > { \
    > return T##_begin; \
    > }
    >
    > enum Piece {none,pawn,knight,bishop,rook,queen,king,
    > Piece_begin = pawn, Piece_end = king + 1};
    > DeclareEnumTricks(Piece)
    >
    > int main()
    > {
    > Piece p = none;
    > cout << p << " " << p++ << " " << ++p << endl;
    > }
    >
    > The output from g++ and several other compilers is _not_
    >
    > 0 0 2
    >
    > as expected. In g++ it is
    >
    > 2 1 1
    >
    > Is there a bug in the code, or in the compilers?
    >
    > /David



    Comeau C++ came up with the expected output: 0 0 2
    Sumit Rajan, Jan 15, 2004
    #4
  5. David Rasmussen

    Pete Becker Guest

    Sumit Rajan wrote:
    >
    > > int main()
    > > {
    > > Piece p = none;
    > > cout << p << " " << p++ << " " << ++p << endl;
    > > }
    > >
    > > The output from g++ and several other compilers is _not_
    > >
    > > 0 0 2
    > >
    > > as expected. In g++ it is
    > >
    > > 2 1 1
    > >
    > > Is there a bug in the code, or in the compilers?
    > >
    > > /David

    >
    > Comeau C++ came up with the expected output: 0 0 2


    Doesn't matter what's expected. What matters is what's required. The
    behavior of the program is undefined. Anything goes.

    --

    Pete Becker
    Dinkumware, Ltd. (http://www.dinkumware.com)
    Pete Becker, Jan 15, 2004
    #5
  6. "David Rasmussen" <> wrote in message
    news:bu6vfe$tb8$-c.dk...
    > Fao, Sean wrote:
    > >> cout << p << " " << p++ << " " << ++p << endl;
    > >>Is there a bug in the code, or in the compilers?

    > >
    > >
    > > In the FAQ.

    >
    > Thanks. I've looked, but I can't find anything relevant. Could be

    more
    > specific?
    >


    I couldn't either. Try this:

    http://www.langer.camelot.de/Articles/VSJ/SequencePoints/SequencePoints.html

    Jonathan
    Jonathan Turkanis, Jan 15, 2004
    #6
  7. osmium wrote:
    > David Rasmussen writes:
    >
    >
    >> cout << p << " " << p++ << " " << ++p << endl;

    >
    > Did you allow for the fact that shift left has a lower precedence than
    > postfix ++ and prefix ++?
    >


    Even if, the first p should print out as 0. Shouldn't it?

    /David
    David Rasmussen, Jan 15, 2004
    #7
  8. Pete Becker wrote:
    >
    > Doesn't matter what's expected. What matters is what's required. The
    > behavior of the program is undefined. Anything goes.
    >


    I would sure like to know why...

    /David
    David Rasmussen, Jan 15, 2004
    #8
  9. David Rasmussen

    Fao, Sean Guest

    David Rasmussen wrote:

    > Fao, Sean wrote:
    >>> cout << p << " " << p++ << " " << ++p << endl;
    >>>Is there a bug in the code, or in the compilers?

    >>
    >>
    >> In the FAQ.

    >
    > Thanks. I've looked, but I can't find anything relevant. Could be more
    > specific?


    I thought I had seen it in the C++ FAQ at one time but I might just be
    dreaming. Oh well, it's in the C FAQ for the same reason...

    http://www.eskimo.com/~scs/C-faq/s3.html
    Fao, Sean, Jan 15, 2004
    #9
  10. Thanks!

    I don't know what I was thinking. I know about the sequencing point type
    problem. My mind was focused on the macros. I was sure I had some bug.

    /David
    David Rasmussen, Jan 15, 2004
    #10
  11. David Rasmussen

    Kevin Saff Guest

    "Jonathan Turkanis" <> wrote in message
    news:bu70ff$ebisf$-berlin.de...
    > "David Rasmussen" <> wrote in message
    > news:bu6vfe$tb8$-c.dk...
    > > Fao, Sean wrote:
    > > >> cout << p << " " << p++ << " " << ++p << endl;
    > > >>Is there a bug in the code, or in the compilers?
    > > >
    > > >
    > > > In the FAQ.

    > >
    > > Thanks. I've looked, but I can't find anything relevant. Could be

    > more
    > > specific?
    > >

    >
    > I couldn't either.


    Neither could I. There must be a bug in the FAQ.

    --
    KCS
    Kevin Saff, Jan 15, 2004
    #11
  12. David Rasmussen wrote:
    > Thanks!
    >
    > I don't know what I was thinking. I know about the sequencing point type
    > problem. My mind was focused on the macros. I was sure I had some bug.
    >


    Where is there a sequence point problem?

    -Kevin
    --
    My email address is valid, but changes periodically.
    To contact me please use the address from a recent posting.
    Kevin Goodsell, Jan 15, 2004
    #12
  13. David Rasmussen

    Ron Natalie Guest

    "David Rasmussen" <> wrote in message news:bu6u3g$sv6$-c.dk...
    > cout << p << " " << p++ << " " << ++p << endl;
    > }
    >
    > The output from g++ and several other compilers is _not_
    >
    > 0 0 2
    >
    > as expected. In g++ it is
    >
    > 2 1 1
    >
    > Is there a bug in the code, or in the compilers?
    >

    In the code. You have undefined behavior. You modify p multiple
    times between sequence point for certain allowable orderings.
    Ron Natalie, Jan 15, 2004
    #13
  14. David Rasmussen

    Ron Natalie Guest

    "Pete Becker" <> wrote in message news:...
    > Doesn't matter what's expected. What matters is what's required. The
    > behavior of the program is undefined. Anything goes.
    >

    Not undefined, it's just that his operators are invoked in an unspecified order.
    Remember there are overloads for the operator++.
    Ron Natalie, Jan 15, 2004
    #14
  15. David Rasmussen

    Ron Natalie Guest

    "David Rasmussen" <> wrote in message news:bu6u3g$sv6$-c.dk...
    => cout << p << " " << p++ << " " << ++p << endl;
    > }


    Argument evaluation order is not fixed in C++. The order of evaluating:
    the three subexpressions "p", "p++" and "++p" is unspecified. Might happen
    left to right, my happen right to left, might happen in any order. All you know
    is that they happen before their respective << operators (but no guarantee
    with respect to each other).
    Ron Natalie, Jan 15, 2004
    #15
  16. David Rasmussen

    Ron Natalie Guest

    "Ron Natalie" <> wrote in message news:400712fa$0$62206$...
    >


    > >

    > In the code. You have undefined behavior. You modify p multiple
    > times between sequence point for certain allowable orderings.
    >


    BZZT. Caught myself here. Not undefined behavior as there are inherent
    sequence points in the function calls. operator ++ is overloaded here.
    Ron Natalie, Jan 15, 2004
    #16
  17. David Rasmussen

    Pete Becker Guest

    David Rasmussen wrote:
    >
    > osmium wrote:
    > > David Rasmussen writes:
    > >
    > >
    > >> cout << p << " " << p++ << " " << ++p << endl;

    > >
    > > Did you allow for the fact that shift left has a lower precedence than
    > > postfix ++ and prefix ++?
    > >

    >
    > Even if, the first p should print out as 0. Shouldn't it?
    >


    Nope. The behavior of the code is undefined, so there's nothing it
    "should" do. I can't tell from your messages whether you've seen what
    the problem is. Here's a simpler version:

    cout << i++ << i++;

    The code modifies the value of i twice without an intervening sequence
    point.

    --

    Pete Becker
    Dinkumware, Ltd. (http://www.dinkumware.com)
    Pete Becker, Jan 15, 2004
    #17
  18. David Rasmussen

    Ron Natalie Guest

    "Pete Becker" <> wrote in message news:...
    > cout << i++ << i++;
    >
    > The code modifies the value of i twice without an intervening sequence
    > point.


    No it does not. The ++ operators are overloads. There are sequence points
    before and after the modification (the ones inherent in calling and returning from
    functions).

    His only sin is to expect that function arguments are to be evaluated in some particular
    order.
    Ron Natalie, Jan 15, 2004
    #18
  19. "Ron Natalie" <> wrote in message
    news:4007164d$0$62213$...
    >
    > "Pete Becker" <> wrote in message

    news:...
    > > cout << i++ << i++;
    > >
    > > The code modifies the value of i twice without an intervening

    sequence
    > > point.

    >
    > No it does not. The ++ operators are overloads. There are

    sequence points
    > before and after the modification (the ones inherent in calling and

    returning from
    > functions).
    >
    > His only sin is to expect that function arguments are to be

    evaluated in some particular
    > order.
    >


    I made the same mistake above.

    Jonathan
    Jonathan Turkanis, Jan 15, 2004
    #19
  20. David Rasmussen

    Pete Becker Guest

    Ron Natalie wrote:
    >
    > "Pete Becker" <> wrote in message news:...
    > > Doesn't matter what's expected. What matters is what's required. The
    > > behavior of the program is undefined. Anything goes.
    > >

    > Not undefined, it's just that his operators are invoked in an unspecified order.
    > Remember there are overloads for the operator++.


    Where is the sequence point between the two increments?

    --

    Pete Becker
    Dinkumware, Ltd. (http://www.dinkumware.com)
    Pete Becker, Jan 15, 2004
    #20
    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. Martin DeMello

    Find.find bug?

    Martin DeMello, Sep 7, 2004, in forum: Ruby
    Replies:
    5
    Views:
    98
    Michal 'hramrach' Suchanek
    Sep 13, 2004
  2. Wybo Dekker
    Replies:
    1
    Views:
    353
    Yukihiro Matsumoto
    Nov 15, 2005
  3. Jonathan Leighton

    Find.find bug in 1.8.4?

    Jonathan Leighton, Mar 21, 2006, in forum: Ruby
    Replies:
    0
    Views:
    93
    Jonathan Leighton
    Mar 21, 2006
  4. vdvorkin
    Replies:
    0
    Views:
    403
    vdvorkin
    Feb 10, 2011
  5. vdvorkin
    Replies:
    3
    Views:
    811
    vdvorkin
    Feb 14, 2011
Loading...

Share This Page