i = v[i++] results in undefined behavior. Can't understand why.

Discussion in 'C++' started by Armen Tsirunyan, Sep 26, 2010.

  1. Please help me, I just can't understand this.
    Clause 1.9 Paragraph 15 (n3092) says:

    Except where noted, evaluations of operands of individual operators
    and of subexpressions of individual
    expressions are unsequenced. [ Note: In an expression that is
    evaluated more than once during the execution
    of a program, unsequenced and indeterminately sequenced evaluations of
    its subexpressions need not be
    performed consistently in different evaluations. —end note ] The value
    computations of the operands of an
    operator are sequenced before the value computation of the result of
    the operator. If a side effect on a scalar
    object is unsequenced relative to either another side effect on the
    same scalar object or a value computation
    using the value of the same scalar object, the behavior is undefined.
    [ Example:
    void f(int, int);
    void g(int i, int* v) {
    i = v[i++]; // the behavior is undefined
    i = 7, i++, i++; // i becomes 9
    i = i++ + 1; // the behavior is undefined
    i = i + 1; // the value of i is incremented
    f(i = -1, i = -1); // the behavior is undefined
    }
    —end example ]

    let's consider i = v[i++]. the side effect of i being incremented by 1
    is SEQUENCED before the side effect of i being assigned v[i++],
    because "The value computations of the operands of an operator are
    sequenced before the value computation of the result of the operator".
    So how come is this undefined behavior?

    Thank you in advance,
    Armen Tsirunyan
    Armen Tsirunyan, Sep 26, 2010
    #1
    1. Advertising

  2. Hello,

    as far as I know a temporary object will be involved when the statement
    is evaluated. Let's call it tmp. Semantically two different thing could
    happen. See below.


    > Please help me, I just can't understand this.
    > Clause 1.9 Paragraph 15 (n3092) says:
    >
    > Except where noted, evaluations of operands of individual operators
    > and of subexpressions of individual
    > expressions are unsequenced. [ Note: In an expression that is
    > evaluated more than once during the execution
    > of a program, unsequenced and indeterminately sequenced evaluations of
    > its subexpressions need not be
    > performed consistently in different evaluations. —end note ] The value
    > computations of the operands of an
    > operator are sequenced before the value computation of the result of
    > the operator. If a side effect on a scalar
    > object is unsequenced relative to either another side effect on the
    > same scalar object or a value computation
    > using the value of the same scalar object, the behavior is undefined.
    > [ Example:
    > void f(int, int);
    > void g(int i, int* v) {
    > i = v[i++]; // the behavior is undefined
    > i = 7, i++, i++; // i becomes 9
    > i = i++ + 1; // the behavior is undefined
    > i = i + 1; // the value of i is incremented
    > f(i = -1, i = -1); // the behavior is undefined
    > }
    > —end example ]
    >
    > let's consider i = v[i++]. the side effect of i being incremented by 1
    > is SEQUENCED before the side effect of i being assigned v[i++],
    > because "The value computations of the operands of an operator are
    > sequenced before the value computation of the result of the operator".
    > So how come is this undefined behavior?


    First evaluation order
    tmp := v ; increment i ; i := tmp.

    Second evalutaion order:
    tmp := v ; i:= tmp ; increment i;

    In the first case we gain i+1 := v, whereas in the second case we
    gain i = v[i+1].

    Yours,
    Andreas



    >
    > Thank you in advance,
    > Armen Tsirunyan
    Andreas Milton M, Sep 26, 2010
    #2
    1. Advertising

  3. Armen Tsirunyan wrote:

    > Please help me, I just can't understand this.
    > Clause 1.9 Paragraph 15 (n3092) says:
    >
    > Except where noted, evaluations of operands of individual operators
    > and of subexpressions of individual
    > expressions are unsequenced. [ Note: In an expression that is
    > evaluated more than once during the execution
    > of a program, unsequenced and indeterminately sequenced evaluations of
    > its subexpressions need not be
    > performed consistently in different evaluations. —end note ] The value
    > computations of the operands of an
    > operator are sequenced before the value computation of the result of
    > the operator. If a side effect on a scalar
    > object is unsequenced relative to either another side effect on the
    > same scalar object or a value computation
    > using the value of the same scalar object, the behavior is undefined.
    > [ Example:
    > void f(int, int);
    > void g(int i, int* v) {
    > i = v[i++]; // the behavior is undefined
    > i = 7, i++, i++; // i becomes 9
    > i = i++ + 1; // the behavior is undefined
    > i = i + 1; // the value of i is incremented
    > f(i = -1, i = -1); // the behavior is undefined
    > }
    > —end example ]
    >
    > let's consider i = v[i++]. the side effect of i being incremented by 1
    > is SEQUENCED before the side effect of i being assigned v[i++],
    > because "The value computations of the operands of an operator are
    > sequenced before the value computation of the result of the operator".
    > So how come is this undefined behavior?
    >


    Because value computations do not include side effects. So you have two
    unsequenced side effects in your snippet (the increment and assignment).
    Moreover you have a value computation on i (left i) that is unsequenced
    relative to a side effect on i (the right "i++").

    If you write this as "i = v[++i]", which is equivalent to "i = *(v + (i = i
    + 1))" you will not have two unsequenced side effects anymore, because the
    assignment in "i = i + 1" is sequenced before the assignment in "i = *(...".
    BUT you still have the same value computation be unsequenced to the same
    side effect as in your snippet. So for both the pre and postfix version you
    have undefined behavior.
    Johannes Schaub (litb), Sep 26, 2010
    #3
  4. Hello,

    As far as I know during the evaluation of "i = v[i++]" two semantically
    different things could happen. It is easier to see that by replacing the
    the =-operator by a pseudo-code function assign(x,y) which realizes x = y.

    First evaluation of assign(i, v[i++]):

    Evaluate i, then add v[i++] to i.
    We gain i := 1 + v

    Second evaluation of assign(i, v[i++]):
    Evaluate i++, then evaluate i, evaluate v

    The side-effect modifies i before we evaluate the index operator.
    Then we gain i = v[i+1]

    The order of expression evaluation is not uniquely determined. I think
    this is what the phrase you cite from clause 1.9 paragraph 15 (n3092)
    is about:

    "Except where noted, evaluations of operands of individual operators
    and of subexpressions of individual expressions are unsequenced. "

    (unsequenced = order not uniquely specified)

    Yours,
    Andreas



    On 09/26/2010 05:36 PM, Armen Tsirunyan wrote:
    > Please help me, I just can't understand this.
    > Clause 1.9 Paragraph 15 (n3092) says:
    >
    > Except where noted, evaluations of operands of individual operators
    > and of subexpressions of individual
    > expressions are unsequenced. [ Note: In an expression that is
    > evaluated more than once during the execution
    > of a program, unsequenced and indeterminately sequenced evaluations of
    > its subexpressions need not be
    > performed consistently in different evaluations. —end note ] The value
    > computations of the operands of an
    > operator are sequenced before the value computation of the result of
    > the operator. If a side effect on a scalar
    > object is unsequenced relative to either another side effect on the
    > same scalar object or a value computation
    > using the value of the same scalar object, the behavior is undefined.
    > [ Example:
    > void f(int, int);
    > void g(int i, int* v) {
    > i = v[i++]; // the behavior is undefined
    > i = 7, i++, i++; // i becomes 9
    > i = i++ + 1; // the behavior is undefined
    > i = i + 1; // the value of i is incremented
    > f(i = -1, i = -1); // the behavior is undefined
    > }
    > —end example ]
    >
    > let's consider i = v[i++]. the side effect of i being incremented by 1
    > is SEQUENCED before the side effect of i being assigned v[i++],
    > because "The value computations of the operands of an operator are
    > sequenced before the value computation of the result of the operator".
    > So how come is this undefined behavior?
    >
    > Thank you in advance,
    > Armen Tsirunyan
    Andreas Milton M, Sep 26, 2010
    #4
  5. On Sep 26, 10:00 pm, "Johannes Schaub (litb)" <>
    wrote:
    > Armen Tsirunyan wrote:
    > > Please help me, I just can't understand this.
    > > Clause 1.9 Paragraph 15 (n3092) says:

    >
    > > Except where noted, evaluations of operands of individual operators
    > > and of subexpressions of individual
    > > expressions are unsequenced. [ Note: In an expression that is
    > > evaluated more than once during the execution
    > > of a program, unsequenced and indeterminately sequenced evaluations of
    > > its subexpressions need not be
    > > performed consistently in different evaluations. —end note ] The value
    > > computations of the operands of an
    > > operator are sequenced before the value computation of the result of
    > > the operator. If a side effect on a scalar
    > > object is unsequenced relative to either another side effect on the
    > > same scalar object or a value computation
    > > using the value of the same scalar object, the behavior is undefined.
    > > [ Example:
    > > void f(int, int);
    > > void g(int i, int* v) {
    > > i = v[i++]; // the behavior is undefined
    > > i = 7, i++, i++; // i becomes 9
    > > i = i++ + 1; // the behavior is undefined
    > > i = i + 1; // the value of i is incremented
    > > f(i = -1, i = -1); // the behavior is undefined
    > > }
    > > —end example ]

    >
    > > let's consider i = v[i++]. the side effect of i being incremented by 1
    > > is SEQUENCED before the side effect of i being assigned v[i++],
    > > because "The value computations of the operands of an operator are
    > > sequenced before the value computation of the result of the operator".
    > > So how come is this undefined behavior?

    >
    > Because value computations do not include side effects. So you have two
    > unsequenced side effects in your snippet (the increment and assignment).


    Thanks, I understand this now.

    > Moreover you have a value computation on i (left i) that is unsequenced
    > relative to a side effect on i (the right "i++").


    But I don't understand this, is there a value computation of the left
    i here? I mean an lvalue is expected here, which as I understand
    means the object not the value. I mean this is rather an object
    identification rather than value computation. Is there a more formal
    definition of what a value computation is and what a side effect on an
    object is?
    Armen Tsirunyan, Sep 26, 2010
    #5
  6. Hello,

    As far as I know during the evaluation of "i = v[i++]" two semantically
    different things could happen. It is easier to see that by replacing the
    the =-operator by a pseudo-code function assign(x,y) which realizes x = y.

    First evaluation of assign(i, v[i++]):

    Evaluate i, then associate v[i++] to i.
    We gain i := 1 + v

    Second evaluation of assign(i, v[i++]):
    Evaluate i++, then evaluate i, evaluate v

    The side-effect modifies i before we evaluate the index operator.
    Then we gain i = v[i+1]

    The order of expression evaluation is not uniquely determined. I think
    this is what the phrase you cite from clause 1.9 paragraph 15 (n3092)
    is about:

    "Except where noted, evaluations of operands of individual operators
    and of subexpressions of individual expressions are unsequenced. "

    (unsequenced = order not uniquely specified)

    Yours,
    Andreas



    On 09/26/2010 05:36 PM, Armen Tsirunyan wrote:
    > Please help me, I just can't understand this.
    > Clause 1.9 Paragraph 15 (n3092) says:
    >
    > Except where noted, evaluations of operands of individual operators
    > and of subexpressions of individual
    > expressions are unsequenced. [ Note: In an expression that is
    > evaluated more than once during the execution
    > of a program, unsequenced and indeterminately sequenced evaluations of
    > its subexpressions need not be
    > performed consistently in different evaluations. —end note ] The value
    > computations of the operands of an
    > operator are sequenced before the value computation of the result of
    > the operator. If a side effect on a scalar
    > object is unsequenced relative to either another side effect on the
    > same scalar object or a value computation
    > using the value of the same scalar object, the behavior is undefined.
    > [ Example:
    > void f(int, int);
    > void g(int i, int* v) {
    > i = v[i++]; // the behavior is undefined
    > i = 7, i++, i++; // i becomes 9
    > i = i++ + 1; // the behavior is undefined
    > i = i + 1; // the value of i is incremented
    > f(i = -1, i = -1); // the behavior is undefined
    > }
    > —end example ]
    >
    > let's consider i = v[i++]. the side effect of i being incremented by 1
    > is SEQUENCED before the side effect of i being assigned v[i++],
    > because "The value computations of the operands of an operator are
    > sequenced before the value computation of the result of the operator".
    > So how come is this undefined behavior?
    >
    > Thank you in advance,
    > Armen Tsirunyan
    Andreas Milton M, Sep 26, 2010
    #6
  7. On Sep 26, 10:00 pm, "Johannes Schaub (litb)" <>
    wrote:
    > Armen Tsirunyan wrote:
    > > Please help me, I just can't understand this.
    > > Clause 1.9 Paragraph 15 (n3092) says:

    >
    > > Except where noted, evaluations of operands of individual operators
    > > and of subexpressions of individual
    > > expressions are unsequenced. [ Note: In an expression that is
    > > evaluated more than once during the execution
    > > of a program, unsequenced and indeterminately sequenced evaluations of
    > > its subexpressions need not be
    > > performed consistently in different evaluations. —end note ] The value
    > > computations of the operands of an
    > > operator are sequenced before the value computation of the result of
    > > the operator. If a side effect on a scalar
    > > object is unsequenced relative to either another side effect on the
    > > same scalar object or a value computation
    > > using the value of the same scalar object, the behavior is undefined.
    > > [ Example:
    > > void f(int, int);
    > > void g(int i, int* v) {
    > > i = v[i++]; // the behavior is undefined
    > > i = 7, i++, i++; // i becomes 9
    > > i = i++ + 1; // the behavior is undefined
    > > i = i + 1; // the value of i is incremented
    > > f(i = -1, i = -1); // the behavior is undefined
    > > }
    > > —end example ]

    >
    > > let's consider i = v[i++]. the side effect of i being incremented by 1
    > > is SEQUENCED before the side effect of i being assigned v[i++],
    > > because "The value computations of the operands of an operator are
    > > sequenced before the value computation of the result of the operator".
    > > So how come is this undefined behavior?

    >
    > Because value computations do not include side effects. So you have two
    > unsequenced side effects in your snippet (the increment and assignment).
    > Moreover you have a value computation on i (left i) that is unsequenced
    > relative to a side effect on i (the right "i++").
    >
    > If you write this as "i = v[++i]", which is equivalent to "i = *(v + (i = i
    > + 1))" you will not have two unsequenced side effects anymore, because the
    > assignment in "i = i + 1" is sequenced before the assignment in "i = *(...".
    > BUT you still have the same value computation be unsequenced to the same
    > side effect as in your snippet. So for both the pre and postfix version you
    > have undefined behavior.


    If I may quote you from another thread :)
    > >   ++i = 0; // defined by c++0x, undefined by C++03
    > >   ++ ++i; // defined by c++0x, undefined by C++03
    > >   i = ++i; // defined by c++0x, undefined by C++03

    >
    > Please disregard the last one. That's still undefined in C++0x it seems.
    > Value computation of the left i is not sequenced relative to the side effect
    > of "++i".


    i = ++i; whether or not this is defined depends pretty much on what a
    value computation means.
    Also, is
    (++i)++;
    defined?
    I guess not, am I right?
    Armen Tsirunyan, Sep 26, 2010
    #7
  8. Armen Tsirunyan wrote:

    > On Sep 26, 10:00 pm, "Johannes Schaub (litb)" <>
    > wrote:
    >> Armen Tsirunyan wrote:
    >> > Please help me, I just can't understand this.
    >> > Clause 1.9 Paragraph 15 (n3092) says:

    >>
    >> > Except where noted, evaluations of operands of individual operators
    >> > and of subexpressions of individual
    >> > expressions are unsequenced. [ Note: In an expression that is
    >> > evaluated more than once during the execution
    >> > of a program, unsequenced and indeterminately sequenced evaluations of
    >> > its subexpressions need not be
    >> > performed consistently in different evaluations. —end note ] The value
    >> > computations of the operands of an
    >> > operator are sequenced before the value computation of the result of
    >> > the operator. If a side effect on a scalar
    >> > object is unsequenced relative to either another side effect on the
    >> > same scalar object or a value computation
    >> > using the value of the same scalar object, the behavior is undefined.
    >> > [ Example:
    >> > void f(int, int);
    >> > void g(int i, int* v) {
    >> > i = v[i++]; // the behavior is undefined
    >> > i = 7, i++, i++; // i becomes 9
    >> > i = i++ + 1; // the behavior is undefined
    >> > i = i + 1; // the value of i is incremented
    >> > f(i = -1, i = -1); // the behavior is undefined
    >> > }
    >> > —end example ]

    >>
    >> > let's consider i = v[i++]. the side effect of i being incremented by 1
    >> > is SEQUENCED before the side effect of i being assigned v[i++],
    >> > because "The value computations of the operands of an operator are
    >> > sequenced before the value computation of the result of the operator".
    >> > So how come is this undefined behavior?

    >>
    >> Because value computations do not include side effects. So you have two
    >> unsequenced side effects in your snippet (the increment and assignment).

    >
    > Thanks, I understand this now.
    >
    >> Moreover you have a value computation on i (left i) that is unsequenced
    >> relative to a side effect on i (the right "i++").

    >
    > But I don't understand this, is there a value computation of the left
    > i here? I mean an lvalue is expected here, which as I understand
    > means the object not the value. I mean this is rather an object
    > identification rather than value computation. Is there a more formal
    > definition of what a value computation is and what a side effect on an
    > object is?


    At 1.9/12 of n3126 it says

    "Evaluation of an expression (or a sub-expression) in general includes both
    value computations (including determining the identity of an object for
    glvalue evaluation and fetching a value previously assigned to an object for
    prvalue evaluation) and initiation of side effects."
    Johannes Schaub (litb), Sep 26, 2010
    #8
  9. Armen Tsirunyan wrote:

    > On Sep 26, 10:00 pm, "Johannes Schaub (litb)" <>
    > wrote:
    >> Armen Tsirunyan wrote:
    >> > Please help me, I just can't understand this.
    >> > Clause 1.9 Paragraph 15 (n3092) says:

    >>
    >> > Except where noted, evaluations of operands of individual operators
    >> > and of subexpressions of individual
    >> > expressions are unsequenced. [ Note: In an expression that is
    >> > evaluated more than once during the execution
    >> > of a program, unsequenced and indeterminately sequenced evaluations of
    >> > its subexpressions need not be
    >> > performed consistently in different evaluations. —end note ] The value
    >> > computations of the operands of an
    >> > operator are sequenced before the value computation of the result of
    >> > the operator. If a side effect on a scalar
    >> > object is unsequenced relative to either another side effect on the
    >> > same scalar object or a value computation
    >> > using the value of the same scalar object, the behavior is undefined.
    >> > [ Example:
    >> > void f(int, int);
    >> > void g(int i, int* v) {
    >> > i = v[i++]; // the behavior is undefined
    >> > i = 7, i++, i++; // i becomes 9
    >> > i = i++ + 1; // the behavior is undefined
    >> > i = i + 1; // the value of i is incremented
    >> > f(i = -1, i = -1); // the behavior is undefined
    >> > }
    >> > —end example ]

    >>
    >> > let's consider i = v[i++]. the side effect of i being incremented by 1
    >> > is SEQUENCED before the side effect of i being assigned v[i++],
    >> > because "The value computations of the operands of an operator are
    >> > sequenced before the value computation of the result of the operator".
    >> > So how come is this undefined behavior?

    >>
    >> Because value computations do not include side effects. So you have two
    >> unsequenced side effects in your snippet (the increment and assignment).
    >> Moreover you have a value computation on i (left i) that is unsequenced
    >> relative to a side effect on i (the right "i++").
    >>
    >> If you write this as "i = v[++i]", which is equivalent to "i = *(v + (i =
    >> i + 1))" you will not have two unsequenced side effects anymore, because
    >> the assignment in "i = i + 1" is sequenced before the assignment in "i =
    >> *(...". BUT you still have the same value computation be unsequenced to
    >> the same side effect as in your snippet. So for both the pre and postfix
    >> version you have undefined behavior.

    >
    > If I may quote you from another thread :)
    >> > ++i = 0; // defined by c++0x, undefined by C++03
    >> > ++ ++i; // defined by c++0x, undefined by C++03
    >> > i = ++i; // defined by c++0x, undefined by C++03

    >>
    >> Please disregard the last one. That's still undefined in C++0x it seems.
    >> Value computation of the left i is not sequenced relative to the side
    >> effect of "++i".

    >
    > i = ++i; whether or not this is defined depends pretty much on what a
    > value computation means.
    > Also, is
    > (++i)++;
    > defined?
    > I guess not, am I right?


    ++i is

    i = i + 1

    The Standard says for postfix i++:

    "The value computation of the ++ expression is sequenced before the
    modification of the operand object."

    And it says for i = x

    "In all cases, the assignment is sequenced after the value computation of
    the right and left operands, and before the value computation of the
    assignment expression."

    Together this means that all side effects are sequenced and all side effects
    are sequenced relative to all value computations. Thus the behavior of
    "(++i)++" is defined.
    Johannes Schaub (litb), Sep 26, 2010
    #9
  10. On Sep 26, 10:53 pm, "Johannes Schaub (litb)" <>
    wrote:
    > Armen Tsirunyan wrote:
    > > On Sep 26, 10:00 pm, "Johannes Schaub (litb)" <>
    > > wrote:
    > >> Armen Tsirunyan wrote:
    > >> > Please help me, I just can't understand this.
    > >> > Clause 1.9 Paragraph 15 (n3092) says:

    >
    > >> > Except where noted, evaluations of operands of individual operators
    > >> > and of subexpressions of individual
    > >> > expressions are unsequenced. [ Note: In an expression that is
    > >> > evaluated more than once during the execution
    > >> > of a program, unsequenced and indeterminately sequenced evaluations of
    > >> > its subexpressions need not be
    > >> > performed consistently in different evaluations. —end note ] The value
    > >> > computations of the operands of an
    > >> > operator are sequenced before the value computation of the result of
    > >> > the operator. If a side effect on a scalar
    > >> > object is unsequenced relative to either another side effect on the
    > >> > same scalar object or a value computation
    > >> > using the value of the same scalar object, the behavior is undefined..
    > >> > [ Example:
    > >> > void f(int, int);
    > >> > void g(int i, int* v) {
    > >> > i = v[i++]; // the behavior is undefined
    > >> > i = 7, i++, i++; // i becomes 9
    > >> > i = i++ + 1; // the behavior is undefined
    > >> > i = i + 1; // the value of i is incremented
    > >> > f(i = -1, i = -1); // the behavior is undefined
    > >> > }
    > >> > —end example ]

    >
    > >> > let's consider i = v[i++]. the side effect of i being incremented by 1
    > >> > is SEQUENCED before the side effect of i being assigned v[i++],
    > >> > because "The value computations of the operands of an operator are
    > >> > sequenced before the value computation of the result of the operator".
    > >> > So how come is this undefined behavior?

    >
    > >> Because value computations do not include side effects. So you have two
    > >> unsequenced side effects in your snippet (the increment and assignment).

    >
    > > Thanks, I understand this now.

    >
    > >> Moreover you have a value computation on i (left i) that is unsequenced
    > >> relative to a side effect on i (the right "i++").

    >
    > > But I don't understand this, is there a value computation of the left
    > > i here? I mean an lvalue is expected here, which as I understand
    > > means the object not the value. I mean this is rather an object
    > > identification rather than value computation. Is there a more formal
    > > definition of what a value computation is and what a side effect on an
    > > object is?

    >
    > At 1.9/12 of n3126 it says
    >
    > "Evaluation of an expression (or a sub-expression) in general includes both
    > value computations (including determining the identity of an object for
    > glvalue evaluation and fetching a value previously assigned to an object for
    > prvalue evaluation) and initiation of side effects."


    so, the incrementation of i in i++ is a side effect, whereas the
    incrementation of i in ++i is a part of value computation, and
    therefore makes ++++i defined. Is that correct?
    Armen Tsirunyan, Sep 26, 2010
    #10
  11. why should ++(i++) be not well-defined?

    Hello,

    To my knowledge the above ++(i++) expression is absolutely well-defined
    since the brackets enforce uniqueness.
    C++ as any language guarantees that subexpressions of an expression are
    evaluated before the expression itself is evaulated. Ambiguities only
    arise in the order of the evaluations of subexpressions, which are
    unsequenced (=unspecified) in C++ for good reason. But here the bracket
    inforces uniqueness. The brackets can be understood as a unary operator.

    We would get the following syntax tree:

    pre-increment
    |
    brackets
    |
    post-increment
    |
    i

    Where is the ambiguity? I don't see any, albeit the expression is ugly
    of course. Even if we take out the brackets the expression would be
    unique, since right increments have higher priority than left increments.

    Cheers,
    Andreas


    On 09/26/2010 07:46 PM, Armen Tsirunyan wrote:
    > On Sep 26, 10:00 pm, "Johannes Schaub (litb)"<>
    > wrote:
    >> Armen Tsirunyan wrote:
    >>> Please help me, I just can't understand this.
    >>> Clause 1.9 Paragraph 15 (n3092) says:

    >>
    >>> Except where noted, evaluations of operands of individual operators
    >>> and of subexpressions of individual
    >>> expressions are unsequenced. [ Note: In an expression that is
    >>> evaluated more than once during the execution
    >>> of a program, unsequenced and indeterminately sequenced evaluations of
    >>> its subexpressions need not be
    >>> performed consistently in different evaluations. —end note ] The value
    >>> computations of the operands of an
    >>> operator are sequenced before the value computation of the result of
    >>> the operator. If a side effect on a scalar
    >>> object is unsequenced relative to either another side effect on the
    >>> same scalar object or a value computation
    >>> using the value of the same scalar object, the behavior is undefined.
    >>> [ Example:
    >>> void f(int, int);
    >>> void g(int i, int* v) {
    >>> i = v[i++]; // the behavior is undefined
    >>> i = 7, i++, i++; // i becomes 9
    >>> i = i++ + 1; // the behavior is undefined
    >>> i = i + 1; // the value of i is incremented
    >>> f(i = -1, i = -1); // the behavior is undefined
    >>> }
    >>> —end example ]

    >>
    >>> let's consider i = v[i++]. the side effect of i being incremented by 1
    >>> is SEQUENCED before the side effect of i being assigned v[i++],
    >>> because "The value computations of the operands of an operator are
    >>> sequenced before the value computation of the result of the operator".
    >>> So how come is this undefined behavior?

    >>
    >> Because value computations do not include side effects. So you have two
    >> unsequenced side effects in your snippet (the increment and assignment).
    >> Moreover you have a value computation on i (left i) that is unsequenced
    >> relative to a side effect on i (the right "i++").
    >>
    >> If you write this as "i = v[++i]", which is equivalent to "i = *(v + (i = i
    >> + 1))" you will not have two unsequenced side effects anymore, because the
    >> assignment in "i = i + 1" is sequenced before the assignment in "i = *(...".
    >> BUT you still have the same value computation be unsequenced to the same
    >> side effect as in your snippet. So for both the pre and postfix version you
    >> have undefined behavior.

    >
    > If I may quote you from another thread :)
    >>> ++i = 0; // defined by c++0x, undefined by C++03
    >>> ++ ++i; // defined by c++0x, undefined by C++03
    >>> i = ++i; // defined by c++0x, undefined by C++03

    >>
    >> Please disregard the last one. That's still undefined in C++0x it seems.
    >> Value computation of the left i is not sequenced relative to the side effect
    >> of "++i".

    >
    > i = ++i; whether or not this is defined depends pretty much on what a
    > value computation means.
    > Also, is
    > (++i)++;
    > defined?
    > I guess not, am I right?
    Andreas Milton M, Sep 26, 2010
    #11
  12. why should ++(i++) be not well-defined?

    Hello,

    You say in your reply that ++(i++) shoould not be well-defined. I don't
    think that's right. please see below.



    On 09/26/2010 07:46 PM, Armen Tsirunyan wrote:
    > On Sep 26, 10:00 pm, "Johannes Schaub (litb)"<>
    > wrote:
    >> Armen Tsirunyan wrote:
    >>> Please help me, I just can't understand this.
    >>> Clause 1.9 Paragraph 15 (n3092) says:

    >>
    >>> Except where noted, evaluations of operands of individual operators
    >>> and of subexpressions of individual
    >>> expressions are unsequenced. [ Note: In an expression that is
    >>> evaluated more than once during the execution
    >>> of a program, unsequenced and indeterminately sequenced evaluations of
    >>> its subexpressions need not be
    >>> performed consistently in different evaluations. —end note ] The value
    >>> computations of the operands of an
    >>> operator are sequenced before the value computation of the result of
    >>> the operator. If a side effect on a scalar
    >>> object is unsequenced relative to either another side effect on the
    >>> same scalar object or a value computation
    >>> using the value of the same scalar object, the behavior is undefined.
    >>> [ Example:
    >>> void f(int, int);
    >>> void g(int i, int* v) {
    >>> i = v[i++]; // the behavior is undefined
    >>> i = 7, i++, i++; // i becomes 9
    >>> i = i++ + 1; // the behavior is undefined
    >>> i = i + 1; // the value of i is incremented
    >>> f(i = -1, i = -1); // the behavior is undefined
    >>> }
    >>> —end example ]

    >>
    >>> let's consider i = v[i++]. the side effect of i being incremented by 1
    >>> is SEQUENCED before the side effect of i being assigned v[i++],
    >>> because "The value computations of the operands of an operator are
    >>> sequenced before the value computation of the result of the operator".
    >>> So how come is this undefined behavior?

    >>
    >> Because value computations do not include side effects. So you have two
    >> unsequenced side effects in your snippet (the increment and assignment).
    >> Moreover you have a value computation on i (left i) that is unsequenced
    >> relative to a side effect on i (the right "i++").
    >>
    >> If you write this as "i = v[++i]", which is equivalent to "i = *(v + (i = i
    >> + 1))" you will not have two unsequenced side effects anymore, because the
    >> assignment in "i = i + 1" is sequenced before the assignment in "i = *(...".
    >> BUT you still have the same value computation be unsequenced to the same
    >> side effect as in your snippet. So for both the pre and postfix version you
    >> have undefined behavior.

    >
    > If I may quote you from another thread :)
    >>> ++i = 0; // defined by c++0x, undefined by C++03
    >>> ++ ++i; // defined by c++0x, undefined by C++03
    >>> i = ++i; // defined by c++0x, undefined by C++03

    >>
    >> Please disregard the last one. That's still undefined in C++0x it seems.
    >> Value computation of the left i is not sequenced relative to the side effect
    >> of "++i".

    >
    > i = ++i; whether or not this is defined depends pretty much on what a
    > value computation means.
    > Also, is
    > (++i)++;
    > defined?
    > I guess not, am I right?



    To my knowledge the above ++(i++) expression is absolutely well-defined
    since the brackets enforce uniqueness.
    C++ as any language guarantees that subexpressions of an expression are
    evaluated before the expression itself is evaulated. Ambiguities only
    arise in the order of the evaluations of subexpressions, which are
    unsequenced (=unspecified) in C++ for good reason. But here the bracket
    inforces uniqueness. The brackets can be understood as a unary operator.

    We would get the following syntax tree:

    pre-increment
    |
    brackets
    |
    post-increment
    |
    i

    Where is the ambiguity? I don't see any, albeit the expression is ugly
    of course. Even if we take out the brackets the expression would be
    unique, since right increments have higher priority than left increments.

    Cheers,
    Andreas
    Andreas Milton M, Sep 26, 2010
    #12
  13. Re: why should ++(i++) be not well-defined?

    On Sep 26, 10:59 pm, Andreas Milton M <>
    wrote:
    > Hello,
    >
    > To my knowledge the above ++(i++) expression is absolutely well-defined
    > since the brackets enforce uniqueness.
    > C++ as any language guarantees that subexpressions of an expression are
    > evaluated before the expression itself is evaulated. Ambiguities only
    > arise in the order of the evaluations of subexpressions, which are
    > unsequenced (=unspecified) in C++ for good reason. But here the bracket
    > inforces uniqueness. The brackets can be understood as a unary operator.
    >
    > We would get the following syntax tree:
    >
    > pre-increment
    >    |
    > brackets
    >    |
    > post-increment
    >    |
    >    i
    >
    > Where is the ambiguity? I don't see any, albeit the expression is ugly
    > of course. Even if we take out the brackets the expression would be
    > unique, since right increments have higher priority than left increments.
    >
    > Cheers,
    > Andreas
    >
    > On 09/26/2010 07:46 PM, Armen Tsirunyan wrote:
    >
    >
    >
    > > On Sep 26, 10:00 pm, "Johannes Schaub (litb)"<>
    > > wrote:
    > >> Armen Tsirunyan wrote:
    > >>> Please help me, I just can't understand this.
    > >>> Clause 1.9 Paragraph 15 (n3092) says:

    >
    > >>> Except where noted, evaluations of operands of individual operators
    > >>> and of subexpressions of individual
    > >>> expressions are unsequenced. [ Note: In an expression that is
    > >>> evaluated more than once during the execution
    > >>> of a program, unsequenced and indeterminately sequenced evaluations of
    > >>> its subexpressions need not be
    > >>> performed consistently in different evaluations. —end note ] The value
    > >>> computations of the operands of an
    > >>> operator are sequenced before the value computation of the result of
    > >>> the operator. If a side effect on a scalar
    > >>> object is unsequenced relative to either another side effect on the
    > >>> same scalar object or a value computation
    > >>> using the value of the same scalar object, the behavior is undefined.
    > >>> [ Example:
    > >>> void f(int, int);
    > >>> void g(int i, int* v) {
    > >>> i = v[i++]; // the behavior is undefined
    > >>> i = 7, i++, i++; // i becomes 9
    > >>> i = i++ + 1; // the behavior is undefined
    > >>> i = i + 1; // the value of i is incremented
    > >>> f(i = -1, i = -1); // the behavior is undefined
    > >>> }
    > >>> —end example ]

    >
    > >>> let's consider i = v[i++]. the side effect of i being incremented by 1
    > >>> is SEQUENCED before the side effect of i being assigned v[i++],
    > >>> because "The value computations of the operands of an operator are
    > >>> sequenced before the value computation of the result of the operator"..
    > >>> So how come is this undefined behavior?

    >
    > >> Because value computations do not include side effects. So you have two
    > >> unsequenced side effects in your snippet (the increment and assignment).
    > >> Moreover you have a value computation on i (left i) that is unsequenced
    > >> relative to a side effect on i (the right "i++").

    >
    > >> If you write this as "i = v[++i]", which is equivalent to "i = *(v + (i = i
    > >> + 1))" you will not have two unsequenced side effects anymore, because the
    > >> assignment in "i = i + 1" is sequenced before the assignment in "i = *(...".
    > >> BUT you still have the same value computation be unsequenced to the same
    > >> side effect as in your snippet. So for both the pre and postfix version you
    > >> have undefined behavior.

    >
    > > If I may quote you from another thread :)
    > >>>    ++i = 0; // defined by c++0x, undefined by C++03
    > >>>    ++ ++i; // defined by c++0x, undefined by C++03
    > >>>    i = ++i; // defined by c++0x, undefined by C++03

    >
    > >> Please disregard the last one. That's still undefined in C++0x it seems.
    > >> Value computation of the left i is not sequenced relative to the side effect
    > >> of "++i".

    >
    > > i = ++i; whether or not this is defined depends pretty much on what a
    > > value computation means.
    > > Also, is
    > > (++i)++;
    > > defined?
    > > I guess not, am I right?


    I wrote (++i)++, not ++(i++), which would be afaik ill-formed since i+
    + is a prvalue. Also I thought that parentheses do notcontribute to
    the order of evaluation of operands or their sequencing, rather, they
    specify the composition tree of the subexpressions in an expression. I
    am so confused right now :)
    Armen Tsirunyan, Sep 26, 2010
    #13
  14. Johannes Schaub (litb) wrote:

    > Armen Tsirunyan wrote:
    >
    >> On Sep 26, 10:00 pm, "Johannes Schaub (litb)" <>
    >> wrote:
    >>> Armen Tsirunyan wrote:
    >>> > Please help me, I just can't understand this.
    >>> > Clause 1.9 Paragraph 15 (n3092) says:
    >>>
    >>> > Except where noted, evaluations of operands of individual operators
    >>> > and of subexpressions of individual
    >>> > expressions are unsequenced. [ Note: In an expression that is
    >>> > evaluated more than once during the execution
    >>> > of a program, unsequenced and indeterminately sequenced evaluations of
    >>> > its subexpressions need not be
    >>> > performed consistently in different evaluations. —end note ] The value
    >>> > computations of the operands of an
    >>> > operator are sequenced before the value computation of the result of
    >>> > the operator. If a side effect on a scalar
    >>> > object is unsequenced relative to either another side effect on the
    >>> > same scalar object or a value computation
    >>> > using the value of the same scalar object, the behavior is undefined.
    >>> > [ Example:
    >>> > void f(int, int);
    >>> > void g(int i, int* v) {
    >>> > i = v[i++]; // the behavior is undefined
    >>> > i = 7, i++, i++; // i becomes 9
    >>> > i = i++ + 1; // the behavior is undefined
    >>> > i = i + 1; // the value of i is incremented
    >>> > f(i = -1, i = -1); // the behavior is undefined
    >>> > }
    >>> > —end example ]
    >>>
    >>> > let's consider i = v[i++]. the side effect of i being incremented by 1
    >>> > is SEQUENCED before the side effect of i being assigned v[i++],
    >>> > because "The value computations of the operands of an operator are
    >>> > sequenced before the value computation of the result of the operator".
    >>> > So how come is this undefined behavior?
    >>>
    >>> Because value computations do not include side effects. So you have two
    >>> unsequenced side effects in your snippet (the increment and assignment).
    >>> Moreover you have a value computation on i (left i) that is unsequenced
    >>> relative to a side effect on i (the right "i++").
    >>>
    >>> If you write this as "i = v[++i]", which is equivalent to "i = *(v + (i
    >>> = i + 1))" you will not have two unsequenced side effects anymore,
    >>> because the assignment in "i = i + 1" is sequenced before the assignment
    >>> in "i = *(...". BUT you still have the same value computation be
    >>> unsequenced to the same side effect as in your snippet. So for both the
    >>> pre and postfix version you have undefined behavior.

    >>
    >> If I may quote you from another thread :)
    >>> > ++i = 0; // defined by c++0x, undefined by C++03
    >>> > ++ ++i; // defined by c++0x, undefined by C++03
    >>> > i = ++i; // defined by c++0x, undefined by C++03
    >>>
    >>> Please disregard the last one. That's still undefined in C++0x it seems.
    >>> Value computation of the left i is not sequenced relative to the side
    >>> effect of "++i".

    >>
    >> i = ++i; whether or not this is defined depends pretty much on what a
    >> value computation means.
    >> Also, is
    >> (++i)++;
    >> defined?
    >> I guess not, am I right?

    >
    > ++i is
    >
    > i = i + 1
    >
    > The Standard says for postfix i++:
    >
    > "The value computation of the ++ expression is sequenced before the
    > modification of the operand object."
    >
    > And it says for i = x
    >
    > "In all cases, the assignment is sequenced after the value computation of
    > the right and left operands, and before the value computation of the
    > assignment expression."
    >
    > Together this means that all side effects are sequenced and all side
    > effects are sequenced relative to all value computations. Thus the
    > behavior of "(++i)++" is defined.


    I suspect you will also need the one you quoted to really nail it down: "The
    value computations of the operands of an operator are sequenced before the
    value computation of the result of the operator.". So in the end, I think
    the defined order is

    glvalue evaluation of i
    assignment to i
    glvalue evaluation of i
    prvalue evaluation of i
    increment of i
    Johannes Schaub (litb), Sep 26, 2010
    #14
  15. Re: why should ++(i++) be not well-defined?

    Armen Tsirunyan wrote:

    > On Sep 26, 10:59 pm, Andreas Milton M <>
    > wrote:
    >> Hello,
    >>
    >> To my knowledge the above ++(i++) expression is absolutely well-defined
    >> since the brackets enforce uniqueness.
    >> C++ as any language guarantees that subexpressions of an expression are
    >> evaluated before the expression itself is evaulated. Ambiguities only
    >> arise in the order of the evaluations of subexpressions, which are
    >> unsequenced (=unspecified) in C++ for good reason. But here the bracket
    >> inforces uniqueness. The brackets can be understood as a unary operator.
    >>
    >> We would get the following syntax tree:
    >>
    >> pre-increment
    >> |
    >> brackets
    >> |
    >> post-increment
    >> |
    >> i
    >>
    >> Where is the ambiguity? I don't see any, albeit the expression is ugly
    >> of course. Even if we take out the brackets the expression would be
    >> unique, since right increments have higher priority than left increments.
    >>
    >> Cheers,
    >> Andreas
    >>
    >> On 09/26/2010 07:46 PM, Armen Tsirunyan wrote:
    >>
    >>
    >>
    >> > On Sep 26, 10:00 pm, "Johannes Schaub (litb)"<>
    >> > wrote:
    >> >> Armen Tsirunyan wrote:
    >> >>> Please help me, I just can't understand this.
    >> >>> Clause 1.9 Paragraph 15 (n3092) says:

    >>
    >> >>> Except where noted, evaluations of operands of individual operators
    >> >>> and of subexpressions of individual
    >> >>> expressions are unsequenced. [ Note: In an expression that is
    >> >>> evaluated more than once during the execution
    >> >>> of a program, unsequenced and indeterminately sequenced evaluations
    >> >>> of its subexpressions need not be
    >> >>> performed consistently in different evaluations. —end note ] The
    >> >>> value computations of the operands of an
    >> >>> operator are sequenced before the value computation of the result of
    >> >>> the operator. If a side effect on a scalar
    >> >>> object is unsequenced relative to either another side effect on the
    >> >>> same scalar object or a value computation
    >> >>> using the value of the same scalar object, the behavior is undefined.
    >> >>> [ Example:
    >> >>> void f(int, int);
    >> >>> void g(int i, int* v) {
    >> >>> i = v[i++]; // the behavior is undefined
    >> >>> i = 7, i++, i++; // i becomes 9
    >> >>> i = i++ + 1; // the behavior is undefined
    >> >>> i = i + 1; // the value of i is incremented
    >> >>> f(i = -1, i = -1); // the behavior is undefined
    >> >>> }
    >> >>> —end example ]

    >>
    >> >>> let's consider i = v[i++]. the side effect of i being incremented by
    >> >>> 1 is SEQUENCED before the side effect of i being assigned v[i++],
    >> >>> because "The value computations of the operands of an operator are
    >> >>> sequenced before the value computation of the result of the
    >> >>> operator". So how come is this undefined behavior?

    >>
    >> >> Because value computations do not include side effects. So you have
    >> >> two unsequenced side effects in your snippet (the increment and
    >> >> assignment). Moreover you have a value computation on i (left i) that
    >> >> is unsequenced relative to a side effect on i (the right "i++").

    >>
    >> >> If you write this as "i = v[++i]", which is equivalent to "i = *(v +
    >> >> (i = i + 1))" you will not have two unsequenced side effects anymore,
    >> >> because the assignment in "i = i + 1" is sequenced before the
    >> >> assignment in "i = *(...". BUT you still have the same value
    >> >> computation be unsequenced to the same side effect as in your snippet.
    >> >> So for both the pre and postfix version you have undefined behavior.

    >>
    >> > If I may quote you from another thread :)
    >> >>> ++i = 0; // defined by c++0x, undefined by C++03
    >> >>> ++ ++i; // defined by c++0x, undefined by C++03
    >> >>> i = ++i; // defined by c++0x, undefined by C++03

    >>
    >> >> Please disregard the last one. That's still undefined in C++0x it
    >> >> seems. Value computation of the left i is not sequenced relative to
    >> >> the side effect of "++i".

    >>
    >> > i = ++i; whether or not this is defined depends pretty much on what a
    >> > value computation means.
    >> > Also, is
    >> > (++i)++;
    >> > defined?
    >> > I guess not, am I right?

    >
    > I wrote (++i)++, not ++(i++), which would be afaik ill-formed since i+
    > + is a prvalue. Also I thought that parentheses do notcontribute to
    > the order of evaluation of operands or their sequencing, rather, they
    > specify the composition tree of the subexpressions in an expression. I
    > am so confused right now :)


    I agree with you on this.
    Johannes Schaub (litb), Sep 26, 2010
    #15
  16. Armen Tsirunyan wrote:

    > On Sep 26, 10:53 pm, "Johannes Schaub (litb)" <>
    > wrote:
    >> Armen Tsirunyan wrote:
    >> > On Sep 26, 10:00 pm, "Johannes Schaub (litb)" <>
    >> > wrote:
    >> >> Armen Tsirunyan wrote:
    >> >> > Please help me, I just can't understand this.
    >> >> > Clause 1.9 Paragraph 15 (n3092) says:

    >>
    >> >> > Except where noted, evaluations of operands of individual operators
    >> >> > and of subexpressions of individual
    >> >> > expressions are unsequenced. [ Note: In an expression that is
    >> >> > evaluated more than once during the execution
    >> >> > of a program, unsequenced and indeterminately sequenced evaluations
    >> >> > of its subexpressions need not be
    >> >> > performed consistently in different evaluations. —end note ] The
    >> >> > value computations of the operands of an
    >> >> > operator are sequenced before the value computation of the result of
    >> >> > the operator. If a side effect on a scalar
    >> >> > object is unsequenced relative to either another side effect on the
    >> >> > same scalar object or a value computation
    >> >> > using the value of the same scalar object, the behavior is
    >> >> > undefined.
    >> >> > [ Example:
    >> >> > void f(int, int);
    >> >> > void g(int i, int* v) {
    >> >> > i = v[i++]; // the behavior is undefined
    >> >> > i = 7, i++, i++; // i becomes 9
    >> >> > i = i++ + 1; // the behavior is undefined
    >> >> > i = i + 1; // the value of i is incremented
    >> >> > f(i = -1, i = -1); // the behavior is undefined
    >> >> > }
    >> >> > —end example ]

    >>
    >> >> > let's consider i = v[i++]. the side effect of i being incremented by
    >> >> > 1 is SEQUENCED before the side effect of i being assigned v[i++],
    >> >> > because "The value computations of the operands of an operator are
    >> >> > sequenced before the value computation of the result of the
    >> >> > operator". So how come is this undefined behavior?

    >>
    >> >> Because value computations do not include side effects. So you have
    >> >> two unsequenced side effects in your snippet (the increment and
    >> >> assignment).

    >>
    >> > Thanks, I understand this now.

    >>
    >> >> Moreover you have a value computation on i (left i) that is
    >> >> unsequenced relative to a side effect on i (the right "i++").

    >>
    >> > But I don't understand this, is there a value computation of the left
    >> > i here? I mean an lvalue is expected here, which as I understand
    >> > means the object not the value. I mean this is rather an object
    >> > identification rather than value computation. Is there a more formal
    >> > definition of what a value computation is and what a side effect on an
    >> > object is?

    >>
    >> At 1.9/12 of n3126 it says
    >>
    >> "Evaluation of an expression (or a sub-expression) in general includes
    >> both value computations (including determining the identity of an object
    >> for glvalue evaluation and fetching a value previously assigned to an
    >> object for prvalue evaluation) and initiation of side effects."

    >
    > so, the incrementation of i in i++ is a side effect, whereas the
    > incrementation of i in ++i is a part of value computation, and
    > therefore makes ++++i defined. Is that correct?


    The increment is not part of value computation. But it is sequenced before a
    value computation and after a value computation since ++i is equivalent to
    i+=1 (which is equivalent to "i = i + 1" except that i is only evaluated
    once as the lhs). So you have a sequence of

    glvalue computation
    increment
    glvalue computation
    increment
    glvalue computation
    .....

    For "++ ... ++ i;" .
    Johannes Schaub (litb), Sep 26, 2010
    #16
  17. Re: why should ++(i++) be not well-defined?

    On 09/26/2010 08:09 PM, Johannes Schaub (litb) wrote:
    > Armen Tsirunyan wrote:
    >
    >> On Sep 26, 10:59 pm, Andreas Milton M<>
    >> wrote:
    >>> Hello,
    >>>
    >>> To my knowledge the above ++(i++) expression is absolutely well-defined
    >>> since the brackets enforce uniqueness.
    >>> C++ as any language guarantees that subexpressions of an expression are
    >>> evaluated before the expression itself is evaulated. Ambiguities only
    >>> arise in the order of the evaluations of subexpressions, which are
    >>> unsequenced (=unspecified) in C++ for good reason. But here the bracket
    >>> inforces uniqueness. The brackets can be understood as a unary operator.
    >>>
    >>> We would get the following syntax tree:
    >>>
    >>> pre-increment
    >>> |
    >>> brackets
    >>> |
    >>> post-increment
    >>> |
    >>> i
    >>>
    >>> Where is the ambiguity? I don't see any, albeit the expression is ugly
    >>> of course. Even if we take out the brackets the expression would be
    >>> unique, since right increments have higher priority than left increments.
    >>>
    >>> Cheers,
    >>> Andreas
    >>>
    >>> On 09/26/2010 07:46 PM, Armen Tsirunyan wrote:
    >>>
    >>>
    >>>
    >>>> On Sep 26, 10:00 pm, "Johannes Schaub (litb)"<>
    >>>> wrote:
    >>>>> Armen Tsirunyan wrote:
    >>>>>> Please help me, I just can't understand this.
    >>>>>> Clause 1.9 Paragraph 15 (n3092) says:
    >>>
    >>>>>> Except where noted, evaluations of operands of individual operators
    >>>>>> and of subexpressions of individual
    >>>>>> expressions are unsequenced. [ Note: In an expression that is
    >>>>>> evaluated more than once during the execution
    >>>>>> of a program, unsequenced and indeterminately sequenced evaluations
    >>>>>> of its subexpressions need not be
    >>>>>> performed consistently in different evaluations. —end note ] The
    >>>>>> value computations of the operands of an
    >>>>>> operator are sequenced before the value computation of the result of
    >>>>>> the operator. If a side effect on a scalar
    >>>>>> object is unsequenced relative to either another side effect on the
    >>>>>> same scalar object or a value computation
    >>>>>> using the value of the same scalar object, the behavior is undefined.
    >>>>>> [ Example:
    >>>>>> void f(int, int);
    >>>>>> void g(int i, int* v) {
    >>>>>> i = v[i++]; // the behavior is undefined
    >>>>>> i = 7, i++, i++; // i becomes 9
    >>>>>> i = i++ + 1; // the behavior is undefined
    >>>>>> i = i + 1; // the value of i is incremented
    >>>>>> f(i = -1, i = -1); // the behavior is undefined
    >>>>>> }
    >>>>>> —end example ]
    >>>
    >>>>>> let's consider i = v[i++]. the side effect of i being incremented by
    >>>>>> 1 is SEQUENCED before the side effect of i being assigned v[i++],
    >>>>>> because "The value computations of the operands of an operator are
    >>>>>> sequenced before the value computation of the result of the
    >>>>>> operator". So how come is this undefined behavior?
    >>>
    >>>>> Because value computations do not include side effects. So you have
    >>>>> two unsequenced side effects in your snippet (the increment and
    >>>>> assignment). Moreover you have a value computation on i (left i) that
    >>>>> is unsequenced relative to a side effect on i (the right "i++").
    >>>
    >>>>> If you write this as "i = v[++i]", which is equivalent to "i = *(v +
    >>>>> (i = i + 1))" you will not have two unsequenced side effects anymore,
    >>>>> because the assignment in "i = i + 1" is sequenced before the
    >>>>> assignment in "i = *(...". BUT you still have the same value
    >>>>> computation be unsequenced to the same side effect as in your snippet.
    >>>>> So for both the pre and postfix version you have undefined behavior.
    >>>
    >>>> If I may quote you from another thread :)
    >>>>>> ++i = 0; // defined by c++0x, undefined by C++03
    >>>>>> ++ ++i; // defined by c++0x, undefined by C++03
    >>>>>> i = ++i; // defined by c++0x, undefined by C++03
    >>>
    >>>>> Please disregard the last one. That's still undefined in C++0x it
    >>>>> seems. Value computation of the left i is not sequenced relative to
    >>>>> the side effect of "++i".
    >>>
    >>>> i = ++i; whether or not this is defined depends pretty much on what a
    >>>> value computation means.
    >>>> Also, is
    >>>> (++i)++;
    >>>> defined?
    >>>> I guess not, am I right?

    >>
    >> I wrote (++i)++, not ++(i++), which would be afaik ill-formed since i+
    >> + is a prvalue. Also I thought that parentheses do notcontribute to
    >> the order of evaluation of operands or their sequencing, rather, they
    >> specify the composition tree of the subexpressions in an expression. I
    >> am so confused right now :)

    >
    > I agree with you on this.


    I'm confused now too, so I'm not quite sure on what we agree or
    disagree. But I'll try to restate my argument in a different shape so
    that you can agree with it or find the mistake.

    Any expression has a unique syntax tree. In order to evaluate one node
    in the tree we need to evaluate all of its children first. The order by
    which we evaluate the subexpressions is unspecified however.
    A side-effect like i++ is not visible at the place where we evaluate the
    expression i++ but at the next time we are confronted with the leaf i in
    the syntax tree. If the next position where we meet i in the syntax tree
    is uniquely specified by the structure of the tree, we have no ambiguity
    problem, otherwise we do.

    Let expr be an expression, then by the grammar of c++ the expression
    (expr) is an expression too. There expression trees must be different,
    otherwise expr and (expr) would be the same expression.
    The expression tree is a subtree of (expr)

    We have an expression tree for expr, call it T_expr.

    The expression tree for (expr) is the tree
    ()
    |
    expr

    You have three choices:
    1) Find the mistake
    2) accept it.
    3) or, if it's giving you too much of a headache, like side-effects
    always do, ignore it :)

    Cheers,
    Andreas
    Andreas Milton M, Sep 26, 2010
    #17
  18. Re: why should ++(i++) be not well-defined?

    On 09/26/2010 08:09 PM, Johannes Schaub (litb) wrote:
    > Armen Tsirunyan wrote:
    >
    >> On Sep 26, 10:59 pm, Andreas Milton M<>
    >> wrote:
    >>> Hello,
    >>>
    >>> To my knowledge the above ++(i++) expression is absolutely well-defined
    >>> since the brackets enforce uniqueness.
    >>> C++ as any language guarantees that subexpressions of an expression are
    >>> evaluated before the expression itself is evaulated. Ambiguities only
    >>> arise in the order of the evaluations of subexpressions, which are
    >>> unsequenced (=unspecified) in C++ for good reason. But here the bracket
    >>> inforces uniqueness. The brackets can be understood as a unary operator.
    >>>
    >>> We would get the following syntax tree:
    >>>
    >>> pre-increment
    >>> |
    >>> brackets
    >>> |
    >>> post-increment
    >>> |
    >>> i
    >>>
    >>> Where is the ambiguity? I don't see any, albeit the expression is ugly
    >>> of course. Even if we take out the brackets the expression would be
    >>> unique, since right increments have higher priority than left increments.
    >>>
    >>> Cheers,
    >>> Andreas
    >>>
    >>> On 09/26/2010 07:46 PM, Armen Tsirunyan wrote:
    >>>
    >>>
    >>>
    >>>> On Sep 26, 10:00 pm, "Johannes Schaub (litb)"<>
    >>>> wrote:
    >>>>> Armen Tsirunyan wrote:
    >>>>>> Please help me, I just can't understand this.
    >>>>>> Clause 1.9 Paragraph 15 (n3092) says:
    >>>
    >>>>>> Except where noted, evaluations of operands of individual operators
    >>>>>> and of subexpressions of individual
    >>>>>> expressions are unsequenced. [ Note: In an expression that is
    >>>>>> evaluated more than once during the execution
    >>>>>> of a program, unsequenced and indeterminately sequenced evaluations
    >>>>>> of its subexpressions need not be
    >>>>>> performed consistently in different evaluations. —end note ] The
    >>>>>> value computations of the operands of an
    >>>>>> operator are sequenced before the value computation of the result of
    >>>>>> the operator. If a side effect on a scalar
    >>>>>> object is unsequenced relative to either another side effect on the
    >>>>>> same scalar object or a value computation
    >>>>>> using the value of the same scalar object, the behavior is undefined.
    >>>>>> [ Example:
    >>>>>> void f(int, int);
    >>>>>> void g(int i, int* v) {
    >>>>>> i = v[i++]; // the behavior is undefined
    >>>>>> i = 7, i++, i++; // i becomes 9
    >>>>>> i = i++ + 1; // the behavior is undefined
    >>>>>> i = i + 1; // the value of i is incremented
    >>>>>> f(i = -1, i = -1); // the behavior is undefined
    >>>>>> }
    >>>>>> —end example ]
    >>>
    >>>>>> let's consider i = v[i++]. the side effect of i being incremented by
    >>>>>> 1 is SEQUENCED before the side effect of i being assigned v[i++],
    >>>>>> because "The value computations of the operands of an operator are
    >>>>>> sequenced before the value computation of the result of the
    >>>>>> operator". So how come is this undefined behavior?
    >>>
    >>>>> Because value computations do not include side effects. So you have
    >>>>> two unsequenced side effects in your snippet (the increment and
    >>>>> assignment). Moreover you have a value computation on i (left i) that
    >>>>> is unsequenced relative to a side effect on i (the right "i++").
    >>>
    >>>>> If you write this as "i = v[++i]", which is equivalent to "i = *(v +
    >>>>> (i = i + 1))" you will not have two unsequenced side effects anymore,
    >>>>> because the assignment in "i = i + 1" is sequenced before the
    >>>>> assignment in "i = *(...". BUT you still have the same value
    >>>>> computation be unsequenced to the same side effect as in your snippet.
    >>>>> So for both the pre and postfix version you have undefined behavior.
    >>>
    >>>> If I may quote you from another thread :)
    >>>>>> ++i = 0; // defined by c++0x, undefined by C++03
    >>>>>> ++ ++i; // defined by c++0x, undefined by C++03
    >>>>>> i = ++i; // defined by c++0x, undefined by C++03
    >>>
    >>>>> Please disregard the last one. That's still undefined in C++0x it
    >>>>> seems. Value computation of the left i is not sequenced relative to
    >>>>> the side effect of "++i".
    >>>
    >>>> i = ++i; whether or not this is defined depends pretty much on what a
    >>>> value computation means.
    >>>> Also, is
    >>>> (++i)++;
    >>>> defined?
    >>>> I guess not, am I right?

    >>
    >> I wrote (++i)++, not ++(i++), which would be afaik ill-formed since i+
    >> + is a prvalue. Also I thought that parentheses do notcontribute to
    >> the order of evaluation of operands or their sequencing, rather, they
    >> specify the composition tree of the subexpressions in an expression. I
    >> am so confused right now :)

    >
    > I agree with you on this.


    You're right. I agree now too.
    Andreas Milton M, Sep 26, 2010
    #18
  19. Armen Tsirunyan

    Bo Persson Guest

    Armen Tsirunyan wrote:
    > On Sep 26, 10:00 pm, "Johannes Schaub (litb)"
    > <> wrote:
    >> Armen Tsirunyan wrote:
    >>> Please help me, I just can't understand this.
    >>> Clause 1.9 Paragraph 15 (n3092) says:

    >>
    >>> Except where noted, evaluations of operands of individual
    >>> operators and of subexpressions of individual
    >>> expressions are unsequenced. [ Note: In an expression that is
    >>> evaluated more than once during the execution
    >>> of a program, unsequenced and indeterminately sequenced
    >>> evaluations of its subexpressions need not be
    >>> performed consistently in different evaluations. —end note ] The
    >>> value computations of the operands of an
    >>> operator are sequenced before the value computation of the result
    >>> of the operator. If a side effect on a scalar
    >>> object is unsequenced relative to either another side effect on
    >>> the same scalar object or a value computation
    >>> using the value of the same scalar object, the behavior is
    >>> undefined. [ Example:
    >>> void f(int, int);
    >>> void g(int i, int* v) {
    >>> i = v[i++]; // the behavior is undefined
    >>> i = 7, i++, i++; // i becomes 9
    >>> i = i++ + 1; // the behavior is undefined
    >>> i = i + 1; // the value of i is incremented
    >>> f(i = -1, i = -1); // the behavior is undefined
    >>> }
    >>> —end example ]

    >>
    >>> let's consider i = v[i++]. the side effect of i being incremented
    >>> by 1 is SEQUENCED before the side effect of i being assigned
    >>> v[i++], because "The value computations of the operands of an
    >>> operator are sequenced before the value computation of the result
    >>> of the operator". So how come is this undefined behavior?

    >>
    >> Because value computations do not include side effects. So you
    >> have two unsequenced side effects in your snippet (the increment
    >> and assignment).

    >
    > Thanks, I understand this now.
    >
    >> Moreover you have a value computation on i (left i) that is
    >> unsequenced relative to a side effect on i (the right "i++").

    >
    > But I don't understand this, is there a value computation of the
    > left i here? I mean an lvalue is expected here, which as I
    > understand means the object not the value. I mean this is rather an
    > object identification rather than value computation. Is there a
    > more formal definition of what a value computation is and what a
    > side effect on an object is?


    You have two side effects here, storing the result of i++ and storing
    the result of the assignment to i. The fact that they are both
    performed without an intervening sequence point is what causes the
    undefined behavior.

    My understanding is that the committee knows about hardware where this
    actually doesn't work, so they defined the language accordingly.



    Bo Persson
    Bo Persson, Sep 26, 2010
    #19
  20. Armen Tsirunyan

    James Kanze Guest

    On Sep 26, 6:57 pm, "Johannes Schaub (litb)" <>
    wrote:
    > Armen Tsirunyan wrote:


    [...]
    > > i = ++i; whether or not this is defined depends pretty much
    > > on what a value computation means.


    It means what it says: the computation of the *value* of the
    expression, without any side effects.

    > > Also, is
    > > (++i)++;
    > > defined?
    > > I guess not, am I right?


    > ++i is


    > i = i + 1


    > The Standard says for postfix i++:


    > "The value computation of the ++ expression is sequenced before the
    > modification of the operand object."


    > And it says for i = x


    > "In all cases, the assignment is sequenced after the value
    > computation of the right and left operands, and before the
    > value computation of the assignment expression."


    > Together this means that all side effects are sequenced and
    > all side effects are sequenced relative to all value
    > computations. Thus the behavior of "(++i)++" is defined.


    Where do you get that from? The sentences you quote only speak
    of sequencing the *value* computation. Nothing about side
    effects.

    --
    James Kanze
    James Kanze, Sep 27, 2010
    #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. REH
    Replies:
    25
    Views:
    819
    Victor Bazarov
    Mar 29, 2005
  2. Mantorok Redgormor
    Replies:
    70
    Views:
    1,731
    Dan Pop
    Feb 17, 2004
  3. Mr. SweatyFinger

    why why why why why

    Mr. SweatyFinger, Nov 28, 2006, in forum: ASP .Net
    Replies:
    4
    Views:
    855
    Mark Rae
    Dec 21, 2006
  4. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,756
    Smokey Grindel
    Dec 2, 2006
  5. 冷雨

    Can't understand String#split's behavior

    冷雨, Oct 17, 2010, in forum: Ruby
    Replies:
    2
    Views:
    80
    冷雨
    Oct 17, 2010
Loading...

Share This Page