post and pre-increment operator overloading not behaving like

Discussion in 'C++' started by simudream@gmail.com, Nov 21, 2007.

  1. Guest

    //hi maybe helpful others can look at this code and
    //tell me why the class code won't behave like
    //intrinsic types with post and pre increment

    //Version: 1.00

    #include <iostream>
    using std::cout;
    using std::endl;
    using std::eek:stream;

    class IntWrapper
    {
    friend ostream & operator<<( ostream&, const IntWrapper& );

    public:
    IntWrapper( int val = 0 ) : i(val) {;}

    IntWrapper operator+( const IntWrapper& rhs) const
    {
    //use RVO
    return IntWrapper( this->i + rhs.i );
    }

    IntWrapper& operator++()
    {
    ++this->i;
    return *this;
    }

    IntWrapper operator++(int)
    {
    IntWrapper tmp(*this);
    this->operator++();
    return tmp;
    }

    private:
    int i;

    };

    ostream &operator<<( ostream &, const IntWrapper & );

    int main()
    {
    //interesting results of the post and pre increment operators

    IntWrapper test;
    int i = 0;

    IntWrapper test1 = test + test++;
    int test2 = i + i++;

    //test1 should be the same as test2 but they are not

    cout << test1 << " <- This should be the same as this one -> " <<
    test2 << endl;

    cout << i << i++ << test << test++ << endl;

    system("pause");
    }

    ostream &operator<<( ostream &output, const IntWrapper &r )
    {
    output << r.i;
    return output;
    }
     
    , Nov 21, 2007
    #1
    1. Advertising

  2. Kai-Uwe Bux Guest

    Re: post and pre-increment operator overloading not behaving like intrinsic types. inc:EXAMPLE (please help)

    wrote:

    > //hi maybe helpful others can look at this code and
    > //tell me why the class code won't behave like
    > //intrinsic types with post and pre increment

    [snip]
    > IntWrapper test1 = test + test++;
    > int test2 = i + i++;
    >
    > //test1 should be the same as test2 but they are not


    As far as I can see you have unspecified behavior according to clause [5/4]
    of the standard. Your assumption that both lines should behave the same is
    not waranted by the standard.


    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Nov 21, 2007
    #2
    1. Advertising

  3. James Kanze Guest

    On Nov 21, 6:52 am, Kai-Uwe Bux <> wrote:
    > wrote:
    > > //hi maybe helpful others can look at this code and
    > > //tell me why the class code won't behave like
    > > //intrinsic types with post and pre increment

    > [snip]
    > > IntWrapper test1 = test + test++;
    > > int test2 = i + i++;


    > > //test1 should be the same as test2 but they are not


    > As far as I can see you have unspecified behavior according to
    > clause [5/4] of the standard.


    Not unspecified. Undefined. At least in the second line. (The
    first is unspecified.)

    > Your assumption that both lines should behave the same is not
    > waranted by the standard.


    The assumption that his program doesn't reformat his hard disk
    is not warranted by the standard.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Nov 21, 2007
    #3
  4. Kai-Uwe Bux Guest

    Re: post and pre-increment operator overloading not behaving like intrinsic types. inc:EXAMPLE (please help)

    James Kanze wrote:

    > On Nov 21, 6:52 am, Kai-Uwe Bux <> wrote:
    >> wrote:
    >> > //hi maybe helpful others can look at this code and
    >> > //tell me why the class code won't behave like
    >> > //intrinsic types with post and pre increment

    >> [snip]
    >> > IntWrapper test1 = test + test++;
    >> > int test2 = i + i++;

    >
    >> > //test1 should be the same as test2 but they are not

    >
    >> As far as I can see you have unspecified behavior according to
    >> clause [5/4] of the standard.

    >
    > Not unspecified. Undefined. At least in the second line.


    Well, I don't see a variable that has its value modified twice between
    sequence points. So it must be the condition

    "Furthermore, the prior value shall be accessed only to determine the
    value to be stored."

    and I have to admit that I never have been able to figure out the meaning of
    this sentence.

    > (The first is unspecified.)


    Yup.

    [snip]


    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Nov 21, 2007
    #4
  5. * Kai-Uwe Bux:
    > James Kanze wrote:
    >
    >> On Nov 21, 6:52 am, Kai-Uwe Bux <> wrote:
    >>> wrote:
    >>>> //hi maybe helpful others can look at this code and
    >>>> //tell me why the class code won't behave like
    >>>> //intrinsic types with post and pre increment
    >>> [snip]
    >>>> IntWrapper test1 = test + test++;
    >>>> int test2 = i + i++;
    >>>> //test1 should be the same as test2 but they are not
    >>> As far as I can see you have unspecified behavior according to
    >>> clause [5/4] of the standard.

    >> Not unspecified. Undefined. At least in the second line.

    >
    > Well, I don't see a variable that has its value modified twice between
    > sequence points. So it must be the condition
    >
    > "Furthermore, the prior value shall be accessed only to determine the
    > value to be stored."
    >
    > and I have to admit that I never have been able to figure out the meaning of
    > this sentence.


    It's probably intended to mean that if an epression modifies a variable,
    the expression shall not use the prior value of the variable for
    anything else than the computation of the new value, e.g. not displayed
    or stored elsewhere. That way the compiler can optimize prematurely to
    its heart content without ensuring that the value is consistent during
    the evaluation of the expression. But as the incorrect examples in the
    standard demonstrate, this part of the standard is bungled, and one must
    therefore ignore it & apply common sense instead of the literal wording.

    Common sense is to not use side effects in sub-expressions.

    Cheers, & hth.

    - Alf

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Nov 21, 2007
    #5
  6. Andre Kostur Guest

    Re: post and pre-increment operator overloading not behaving like intrinsic types. inc:EXAMPLE (please help)

    wrote in news:d49de4fe-d494-4f62-b5cf-
    :

    > //hi maybe helpful others can look at this code and
    > //tell me why the class code won't behave like
    > //intrinsic types with post and pre increment
    >
    > //Version: 1.00
    >

    [snip code which, IMHO, is correct]

    > int main()
    > {
    > //interesting results of the post and pre increment operators
    >
    > IntWrapper test;
    > int i = 0;
    >
    > IntWrapper test1 = test + test++;


    Undefined Behaviour. Reading and modifying a value without an
    intervening sequence point.

    > int test2 = i + i++;


    Undefined Behaviour. Reading and modifying a value without an
    intervening sequence point. And apparently the Undefined Behaviour is
    different between basic types and user defined classes.

    >
    > //test1 should be the same as test2 but they are not
    >
    > cout << test1 << " <- This should be the same as this one -> " <<
    > test2 << endl;
    >
    > cout << i << i++ << test << test++ << endl;
    >
    > system("pause");
    > }
     
    Andre Kostur, Nov 21, 2007
    #6
  7. James Kanze Guest

    On Nov 21, 1:44 pm, Kai-Uwe Bux <> wrote:
    > James Kanze wrote:
    > > On Nov 21, 6:52 am, Kai-Uwe Bux <> wrote:
    > >> wrote:
    > >> > //hi maybe helpful others can look at this code and
    > >> > //tell me why the class code won't behave like
    > >> > //intrinsic types with post and pre increment
    > >> [snip]
    > >> > IntWrapper test1 = test + test++;
    > >> > int test2 = i + i++;


    > >> > //test1 should be the same as test2 but they are not


    > >> As far as I can see you have unspecified behavior according to
    > >> clause [5/4] of the standard.


    > > Not unspecified. Undefined. At least in the second line.


    > Well, I don't see a variable that has its value modified twice
    > between sequence points. So it must be the condition


    > "Furthermore, the prior value shall be accessed only to
    > determine the value to be stored."


    > and I have to admit that I never have been able to figure out
    > the meaning of this sentence.


    It could be clearer, but what it basically means is that if you
    modify the variable, the only legal accesses without an
    intervening sequence point are those which are used to determine
    the new value. Intuitively, if there is no sequence point, then
    cause and effect ordering may still render the code legal: in an
    expression like "a = a + 1", there may not be a sequence point
    between the two accesses to a, but it's quite clear that the
    read must be occur before the write, since we can't know what to
    write until the read has occured.

    In some ways, the rule is very much like the rule for accessing
    in a multithreaded environment: if any access is a modification,
    then all accesses must be "protected". Here, the protection may
    be provided by an intervening sequence point, or by a strict
    value dependency.

    IMHO, the word "prior" in the quoted sentence only causes
    confusion. In an expression such as "i + i++", does the first i
    access the "prior" value, or some later value. In fact, the
    standard states elsewhere that there is undefined behavior is
    any legal ordering would result in undefined behavior. Since
    the ordering which evaluates the left hand side of the +
    operator first does access the "prior" value, the expression has
    undefined behavior. But as there are no cases without an
    intervening sequence point which don't allow such reordering,
    the "prior" is really not needed.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Nov 22, 2007
    #7
  8. James Kanze Guest

    On Nov 21, 2:18 pm, "Alf P. Steinbach" <> wrote:
    > * Kai-Uwe Bux:
    > > James Kanze wrote:
    > >> On Nov 21, 6:52 am, Kai-Uwe Bux <> wrote:
    > >>> wrote:
    > >>>> //hi maybe helpful others can look at this code and
    > >>>> //tell me why the class code won't behave like
    > >>>> //intrinsic types with post and pre increment
    > >>> [snip]
    > >>>> IntWrapper test1 = test + test++;
    > >>>> int test2 = i + i++;
    > >>>> //test1 should be the same as test2 but they are not
    > >>> As far as I can see you have unspecified behavior according to
    > >>> clause [5/4] of the standard.
    > >> Not unspecified. Undefined. At least in the second line.


    > > Well, I don't see a variable that has its value modified
    > > twice between sequence points. So it must be the condition


    > > "Furthermore, the prior value shall be accessed only to
    > > determine the value to be stored."


    > > and I have to admit that I never have been able to figure
    > > out the meaning of this sentence.


    > It's probably intended to mean that if an epression modifies a
    > variable, the expression shall not use the prior value of the
    > variable for anything else than the computation of the new
    > value, e.g. not displayed or stored elsewhere.


    The prior value may not be accessed, period, other than to
    determine the new value. You don't have to display or store it
    elsewhere---you just have to use it in an expression. (Of
    course, I'm not sure that means anything in practice. But it's
    what the standard says.)

    > That way the compiler can optimize prematurely to its heart
    > content without ensuring that the value is consistent during
    > the evaluation of the expression. But as the incorrect
    > examples in the standard demonstrate,


    Which "incorrect examples"? The only incorrection I see in the
    examples is the use of the word "unspecified" rather than
    "undefined" in the comments. The preceding (normative) text
    makes it quite clear, however, that the behavior in the examples
    is undefined. (There are other cases where it isn't so clear,
    of course.)

    > this part of the standard is bungled, and one must therefore
    > ignore it & apply common sense instead of the literal wording.


    That's your opinion, and it isn't shared by the experts (unless
    you mean something different by "bungled" than I understand).

    Generally speaking, it is recognized that the model used to
    express the constraints here is not ideal. The C committee
    discussed the issues when updating the C standard (resulting in
    C99). The consensus among the experts at the time was that
    while not the best, the current wording was sufficient for what
    was wanted, and that a rewrite wasn't necessary. (The rules
    here are taken verbatim from the C standard.)

    Of course, the rules don't address threading issues. Since the
    C++ standard is addressing threading, this section does require
    rework, and is the subject of a complete rewrite. In
    collaboration with the C committee---the intent is that whatever
    we rewrite will be acceptable to them, and integrated into the
    next version of the C standard as well.

    > Common sense is to not use side effects in sub-expressions.


    Ideally: each statement does one thing, and one thing only. A
    flow control statement doesn't modify program state, and a
    statement which modifies an object doesn't modify any other
    program state, nor affect flow control.

    Practically, there are exceptions. But they should be very
    rare (and almost always concern modifying state in a flow
    control statement, and not modifying two different objects in a
    single statement).

    Hopefully, we've gotten past the days when people thought that
    things like:
    while ( *p ++ = *q ++ ) ;
    was acceptable in production code.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Nov 22, 2007
    #8
  9. * James Kanze:
    > On Nov 21, 2:18 pm, "Alf P. Steinbach" <> wrote:
    >> * Kai-Uwe Bux:
    >>> James Kanze wrote:
    >>>> On Nov 21, 6:52 am, Kai-Uwe Bux <> wrote:
    >>>>> wrote:
    >>>>>> //hi maybe helpful others can look at this code and
    >>>>>> //tell me why the class code won't behave like
    >>>>>> //intrinsic types with post and pre increment
    >>>>> [snip]
    >>>>>> IntWrapper test1 = test + test++;
    >>>>>> int test2 = i + i++;
    >>>>>> //test1 should be the same as test2 but they are not
    >>>>> As far as I can see you have unspecified behavior according to
    >>>>> clause [5/4] of the standard.
    >>>> Not unspecified. Undefined. At least in the second line.

    >
    >>> Well, I don't see a variable that has its value modified
    >>> twice between sequence points. So it must be the condition

    >
    >>> "Furthermore, the prior value shall be accessed only to
    >>> determine the value to be stored."

    >
    >>> and I have to admit that I never have been able to figure
    >>> out the meaning of this sentence.

    >
    >> It's probably intended to mean that if an epression modifies a
    >> variable, the expression shall not use the prior value of the
    >> variable for anything else than the computation of the new
    >> value, e.g. not displayed or stored elsewhere.

    >
    > The prior value may not be accessed, period, other than to
    > determine the new value. You don't have to display or store it
    > elsewhere---you just have to use it in an expression. (Of
    > course, I'm not sure that means anything in practice. But it's
    > what the standard says.)


    Exactly how do you think that's different from what I wrote?


    >> That way the compiler can optimize prematurely to its heart
    >> content without ensuring that the value is consistent during
    >> the evaluation of the expression. But as the incorrect
    >> examples in the standard demonstrate,

    >
    > Which "incorrect examples"? The only incorrection I see in the
    > examples is the use of the word "unspecified" rather than
    > "undefined" in the comments. The preceding (normative) text
    > makes it quite clear, however, that the behavior in the examples
    > is undefined. (There are other cases where it isn't so clear,
    > of course.)


    Again, how is that different from what I wrote?


    >> this part of the standard is bungled, and one must therefore
    >> ignore it & apply common sense instead of the literal wording.

    >
    > That's your opinion, and it isn't shared by the experts (unless
    > you mean something different by "bungled" than I understand).


    It's being corrected in C++0x.

    And I remind you that you have participated in extended discussions in
    e.g. comp.std.c++ about what the wording means, where you have taken on
    minority positions.

    Your reference to unspecified "experts" is therefore (a) evidently
    incorrect, and (b) fallacious anyway.


    > Generally speaking, it is recognized that the model used to
    > express the constraints here is not ideal. The C committee
    > discussed the issues when updating the C standard (resulting in
    > C99). The consensus among the experts at the time was that
    > while not the best, the current wording was sufficient for what
    > was wanted, and that a rewrite wasn't necessary. (The rules
    > here are taken verbatim from the C standard.)
    >
    > Of course, the rules don't address threading issues. Since the
    > C++ standard is addressing threading, this section does require
    > rework, and is the subject of a complete rewrite. In
    > collaboration with the C committee---the intent is that whatever
    > we rewrite will be acceptable to them, and integrated into the
    > next version of the C standard as well.


    You may of course, by association, include yourself in the panel of
    people rewriting this stuff, if you're participating in the committee
    (do you, still?), and you may attribute the changes to anything vaguely
    associated. Let the associations run wild. :)


    >> Common sense is to not use side effects in sub-expressions.

    >
    > Ideally: each statement does one thing, and one thing only. A
    > flow control statement doesn't modify program state, and a
    > statement which modifies an object doesn't modify any other
    > program state, nor affect flow control.
    >
    > Practically, there are exceptions. But they should be very
    > rare (and almost always concern modifying state in a flow
    > control statement, and not modifying two different objects in a
    > single statement).
    >
    > Hopefully, we've gotten past the days when people thought that
    > things like:
    > while ( *p ++ = *q ++ ) ;
    > was acceptable in production code.


    It's an idiom, presented in the first version of "The C Programming
    Language" by Kernighan & Ritchie.

    Cheers, & hth.,

    - Alf


    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Nov 22, 2007
    #9
    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. Andreas Sheriff
    Replies:
    10
    Views:
    747
    Jack Klein
    Sep 25, 2004
  2. Replies:
    10
    Views:
    45,230
    gene tani
    Jan 13, 2006
  3. Alf P. Steinbach /Usenet
    Replies:
    0
    Views:
    935
    Alf P. Steinbach /Usenet
    May 22, 2011
  4. Peng Yu

    post increment or pre increment?

    Peng Yu, Nov 21, 2008, in forum: Perl Misc
    Replies:
    7
    Views:
    590
    Peter J. Holzer
    Nov 23, 2008
  5. Yogesh Yadav Pacheria

    Pre And Post Increment Operator Output

    Yogesh Yadav Pacheria, Jun 21, 2012, in forum: C Programming
    Replies:
    46
    Views:
    1,694
    Michael Press
    Jul 13, 2012
Loading...

Share This Page