Undefined Behavior. ..

Discussion in 'C Programming' started by coolguyaroundyou@gmail.com, Nov 15, 2008.

  1. Guest

    Will the following statement invoke undefined behavior :

    a^=b,b^=a,a^=b ;

    given that a and b are of int-type ??

    Be cautious, I have not written a^=b^=a^=b ; which, of course, is
    undefined. I am having some confusion with the former statement!

    Also, state the reason for the statement being undefined!
    , Nov 15, 2008
    #1
    1. Advertising

  2. wrote:
    > Will the following statement invoke undefined behavior :
    >
    > a^=b,b^=a,a^=b ;
    >
    > given that a and b are of int-type ??


    No, because the comma operator constitutes a sequence point

    > Be cautious, I have not written a^=b^=a^=b ; which, of course, is
    > undefined. I am having some confusion with the former statement!
    >
    > Also, state the reason for the statement being undefined!


    6.5.17.1
    The left operand of a comma operator is evaluated as a void expression;
    there is a sequence point after its evaluation.

    Bye, Jojo
    Joachim Schmitz, Nov 15, 2008
    #2
    1. Advertising

  3. Guest

    <<Be cautious, I have not written a^=b^=a^=b ; which, of course, is
    undefined. I am having some confusion with the former statement!>>

    I think this expression is valid as assignment operator is evaluated
    from right to left so it is parsed as
    (a^=(b^=(a^=b)))
    above expression swaps two numbers
    please correct me if i am wrong...
    , Nov 15, 2008
    #3
  4. wrote:
    > <<Be cautious, I have not written a^=b^=a^=b ; which, of course, is
    > undefined. I am having some confusion with the former statement!>>
    >
    > I think this expression is valid as assignment operator is evaluated
    > from right to left so it is parsed as
    > (a^=(b^=(a^=b)))
    > above expression swaps two numbers
    > please correct me if i am wrong...


    This is modifying 'a' twice without an intermediate sequence point ->
    undefined behavoir

    Bye, Jojo
    Joachim Schmitz, Nov 15, 2008
    #4
  5. maverik Guest

    On Nov 15, 3:18 pm, ""
    <> wrote:
    > <<Be cautious, I have not written a^=b^=a^=b ; which, of course, is
    > undefined. I am having some confusion with the former statement!>>
    >
    > I think this expression is valid as assignment operator is evaluated
    > from right to left so it is parsed as
    > (a^=(b^=(a^=b)))


    6.5.17

    1.
    expression:
    assignment-expression
    expression , assignment-expression

    2.
    The left operand of a comma operator is evaluated as a void
    expression; there is a sequence point after its evaluation. Then the
    right operand is evaluated; the result has its type and value.

    So, you have:

    a^=b, b^=a, a^=b
    [expression][assignment-expression]
    |
    a^=b, b^=a
    [expression][assignment-expression]
    |
    a^=b
    [assignment-expression]

    OTOH, a^=b, b^=a, a^=b
    [left operand] [right operand]

    Left operand evaluted as void, and comma epression has a type and
    value of right operand: a^=b.
    But left operand if: a^=b, b^=a
    And again: a^=b, b^=a
    [left operand] [right operand]
    Left operand evaluted as void, and comma epression has a type and
    value of right operand: b^=a.

    So, the sequnce should be like:
    evalute a^=b, then b^=a, then a^=b.
    You should get the same result as in this case:

    a^=b;
    b^=a;
    a^=b;
    maverik, Nov 15, 2008
    #5
  6. James Kuyper Guest

    wrote:
    > Will the following statement invoke undefined behavior :
    >
    > a^=b,b^=a,a^=b ;
    >
    > given that a and b are of int-type ??


    That's perfectly safe. As a stand-alone statement, it is exactly
    equivalent to

    a^=b;
    b^=a;
    a^=b;

    The use of the comma operator is only needed in cases like if(A; B; C),
    where A, B, and C can only be a single statement. In any other context,
    I'd recommend breaking it out into three separate statements, but only
    for the sake of clarity - it's perfectly legal as a single statement.

    > Be cautious, I have not written a^=b^=a^=b ; which, of course, is
    > undefined. I am having some confusion with the former statement!
    >
    > Also, state the reason for the statement being undefined!


    6.5p2: "Between the previous and next sequence point an object shall
    have its stored value modified at most once by the evaluation of an
    expression".

    Because the second version violates a "shall" occurring outside of a
    "Constraints" section, the behavior is undefined.

    The key difference between the two statements is the presence of the ','
    operators in the first version. The ',' operator inserts a sequence
    point separating it's two operands.
    James Kuyper, Nov 15, 2008
    #6
  7. Guest

    On Nov 15, 5:24 pm, "Joachim Schmitz" <>
    wrote:
    > wrote:
    > > <<Be cautious, I have not written a^=b^=a^=b ; which, of course, is
    > > undefined. I am having some confusion with the former statement!>>

    >
    > > I think this expression is valid as assignment operator is evaluated
    > > from right to left so it is parsed as
    > > (a^=(b^=(a^=b)))
    > > above expression swaps two numbers
    > > please correct me if i am wrong...

    >
    > This is modifying 'a' twice without an intermediate sequence point ->
    > undefined behavoir
    >
    > Bye, Jojo


    sorry,I am still not able to get it...

    now again consider a^=b^=a^=b
    when compiler see this expression it starts from RHS as assignment
    operator is right associative
    so first it has to calculate rightmost a^=b then value of a must have
    to change....it porceedes then to calculate b^=a ..then again a^=b....

    as we can also use a=b=3;
    Do you mean that after right most a^=b,we can not be sure that value
    of a is changed till we get sequence point...
    but a=b=3 is valid

    Please clear my confusion...
    thanks,
    , Nov 15, 2008
    #7
  8. maverik Guest

    On Nov 15, 3:34 pm, pete <> wrote:
    > You don't have any comma operators in the code that you quoted.


    Ok, I mean this: a^=b,b^=a,a^=b; of course
    maverik, Nov 15, 2008
    #8
  9. Guest

    On Nov 15, 2:39 pm, ""
    <> wrote:
    > On Nov 15, 5:24 pm, "Joachim Schmitz" <>
    > wrote:
    >
    > > wrote:
    > > > <<Be cautious, I have not written a^=b^=a^=b ; which, of course, is
    > > > undefined. I am having some confusion with the former statement!>>

    >
    > > > I think this expression is valid as assignment operator is evaluated
    > > > from right to left so it is parsed as
    > > > (a^=(b^=(a^=b)))
    > > > above expression swaps two numbers
    > > > please correct me if i am wrong...

    >
    > > This is modifying 'a' twice without an intermediate sequence point ->
    > > undefined behavoir

    >
    > > Bye, Jojo

    >
    > sorry,I am still not able to get it...


    What don't you get?

    > now again consider a^=b^=a^=b
    > when compiler see this expression it starts from RHS as assignment


    Wrong, when the compiler sees that expression, he can do whatever he
    wants because that expression invokes undefined behavior.

    > operator is right associative


    Uh, no, it's UB.

    > so first it has to calculate rightmost a^=b then value of a must have


    Uh, no, it's UB.

    > to change....it porceedes then to calculate b^=a ..then again a^=b....


    Uh, no, it's UB.

    > as we can also use a=b=3;


    That's different than the former expression, because in that
    expression a and b are modified only once between sequence points.

    > Do you mean that after right most a^=b,we can not be sure that value


    No, a^=b^=a^=b invokes UB and if you have that in your code, you can't
    be sure of anything at all.

    > but a=b=3 is valid
    > Please clear my confusion...


    For the reasons I explained before. Now I have a question: How the
    hell do you know that a = b = 3 is valid if you don't understand and
    you're confused?
    , Nov 15, 2008
    #9
  10. On Sat, 15 Nov 2008 04:56:25 -0800, vippstar wrote:
    > On Nov 15, 2:39 pm, "" <>
    > wrote:
    >> now again consider a^=b^=a^=b
    >> when compiler see this expression it starts from RHS as assignment

    >
    > Wrong, when the compiler sees that expression, he can do whatever he
    > wants because that expression invokes undefined behavior.


    When the compiler sees that expression, it cannot be sure whether it will
    be executed. It must compile the code, and if the program reaches the
    point where the expression is evaluated, _then_ the behaviour is
    undefined. The compiler cannot do whatever it wants. The compiler can make
    the resulting code do whatever it wants.

    >> operator is right associative

    >
    > Uh, no, it's UB.


    Uh, yes, ^= is right associative. The behaviour is undefined but that does
    not affect parsing.
    Harald van Dijk, Nov 15, 2008
    #10
  11. Guest

    On Nov 15, 3:11 pm, Harald van D©¦k <> wrote:
    > On Sat, 15 Nov 2008 04:56:25 -0800, vippstar wrote:
    > > On Nov 15, 2:39 pm, "c.lang.mys[298]" <c.lang.mys[299]>
    > > wrote:
    > >> now again consider a^=b^=a^=b
    > >> when compiler see this expression it starts from RHS as assignment

    >
    > > Wrong, when the compiler sees that expression, he can do whatever he
    > > wants because that expression invokes undefined behavior.

    >
    > When the compiler sees that expression, it cannot be sure whether it will
    > be executed. It must compile the code, and if the program reaches the
    > point where the expression is evaluated, _then_ the behaviour is
    > undefined. The compiler cannot do whatever it wants. The compiler can make
    > the resulting code do whatever it wants.


    What ELSE could the compiler do other than having the output be
    whatever he wants? I don't think you've really added to what I said.

    > >> operator is right associative

    >
    > > Uh, no, it's UB.

    >
    > Uh, yes, ^= is right associative. The behaviour is undefined but that does
    > not affect parsing.


    Well, UB is when the standard doesn't impose any requirements for the
    behavior of the implementation. You'd argue that 'parsing' is not
    included in 'behavior'? You might be right but I'd like quotes from
    the standard to trust you. (you are certainly credible, but c&v from
    the standard is always nice)
    , Nov 15, 2008
    #11
  12. James Kuyper Guest

    Harald van Dijk wrote:
    > On Sat, 15 Nov 2008 04:56:25 -0800, vippstar wrote:
    >> On Nov 15, 2:39 pm, "" <>
    >> wrote:
    >>> now again consider a^=b^=a^=b
    >>> when compiler see this expression it starts from RHS as assignment

    >> Wrong, when the compiler sees that expression, he can do whatever he
    >> wants because that expression invokes undefined behavior.

    >
    > When the compiler sees that expression, it cannot be sure whether it will
    > be executed. It must compile the code, and if the program reaches the
    > point where the expression is evaluated, _then_ the behaviour is
    > undefined. The compiler cannot do whatever it wants. The compiler can make
    > the resulting code do whatever it wants.


    The standard quite explicitly says that the consequences of undefined
    behavior can include failing to compile, which clearly indicates that it
    can precede execution of the relevant code. The standard does not
    explain this in any detail, but I believe that the relevant rule is that
    the undefined behavior is allowed at any point after execution of the
    relevant code becomes inevitable.

    Example:

    if(some condition)
    a^=b^=a^=b;

    For code like this, the behavior of the code becomes undefined as soon
    as it becomes inevitable that the if() clause will be executed. This
    means that at points in the code prior the if() statement, the compiler
    is allowed to generate code using optimizations that only work if the
    if-condition is not true. As a result, those optimizations may cause
    your code to misbehave long before evaluation of the offending statement.
    James Kuyper, Nov 15, 2008
    #12
  13. On Sat, 15 Nov 2008 13:38:21 +0000, James Kuyper wrote:
    > Harald van Dijk wrote:
    >> On Sat, 15 Nov 2008 04:56:25 -0800, vippstar wrote:
    >>> On Nov 15, 2:39 pm, ""
    >>> <> wrote:
    >>>> now again consider a^=b^=a^=b
    >>>> when compiler see this expression it starts from RHS as assignment
    >>> Wrong, when the compiler sees that expression, he can do whatever he
    >>> wants because that expression invokes undefined behavior.

    >>
    >> When the compiler sees that expression, it cannot be sure whether it
    >> will be executed. It must compile the code, and if the program reaches
    >> the point where the expression is evaluated, _then_ the behaviour is
    >> undefined. The compiler cannot do whatever it wants. The compiler can
    >> make the resulting code do whatever it wants.

    >
    > The standard quite explicitly says that the consequences of undefined
    > behavior can include failing to compile,


    It does quite explicitly say so, but there is a distinction between
    compile-time undefined behaviour and run-time undefined behaviour (not
    spelled out in the standard, but made explicit in DRs). This is run-time
    undefined behaviour, where refusing to compile is permitted only if the
    compiler can prove that the code would always be executed.

    > which clearly indicates that it
    > can precede execution of the relevant code. The standard does not
    > explain this in any detail, but I believe that the relevant rule is that
    > the undefined behavior is allowed at any point after execution of the
    > relevant code becomes inevitable.


    I agree with this.
    Harald van Dijk, Nov 15, 2008
    #13
  14. On Sat, 15 Nov 2008 05:37:35 -0800, vippstar wrote:
    > On Nov 15, 3:11 pm, Harald van Dijk <> wrote:
    >> On Sat, 15 Nov 2008 04:56:25 -0800, vippstar wrote:
    >> > On Nov 15, 2:39 pm, "c.lang.mys[298]"
    >> > <c.lang.mys[299]> wrote:
    >> >> now again consider a^=b^=a^=b
    >> >> when compiler see this expression it starts from RHS as assignment

    >>
    >> > Wrong, when the compiler sees that expression, he can do whatever he
    >> > wants because that expression invokes undefined behavior.

    >>
    >> When the compiler sees that expression, it cannot be sure whether it
    >> will be executed. It must compile the code, and if the program reaches
    >> the point where the expression is evaluated, _then_ the behaviour is
    >> undefined. The compiler cannot do whatever it wants. The compiler can
    >> make the resulting code do whatever it wants.

    >
    > What ELSE could the compiler do other than having the output be whatever
    > he wants? I don't think you've really added to what I said.


    A non-conforming compiler could give an error message and refuse to
    compile any program containing a^=b^=a^=b, but a conforming compiler is
    not allowed to do so (or at least not always).

    >> >> operator is right associative

    >>
    >> > Uh, no, it's UB.

    >>
    >> Uh, yes, ^= is right associative. The behaviour is undefined but that
    >> does not affect parsing.

    >
    > Well, UB is when the standard doesn't impose any requirements for the
    > behavior of the implementation.


    Yes, but to get to the part where the standard says the behaviour is
    undefined you need to have already parsed the expression. I can't give an
    exact chapter and verse, but can you explain how you can determine that
    the behaviour is undefined without parsing?
    Harald van Dijk, Nov 15, 2008
    #14
  15. Guest

    On Nov 15, 4:04 pm, Harald van D©¦k <> wrote:
    > On Sat, 15 Nov 2008 05:37:35 -0800, vippstar wrote:
    > > On Nov 15, 3:11 pm, Harald van D©¦k <true[389]> wrote:
    > >> On Sat, 15 Nov 2008 04:56:25 -0800, vippstar wrote:
    > >> > On Nov 15, 2:39 pm, "c.lang.mys[298].[390]"
    > >> > <c.lang.mys[299].[391]> wrote:
    > >> >> now again consider a^=b^=a^=b
    > >> >> when compiler see this expression it starts from RHS as assignment

    >
    > >> > Wrong, when the compiler sees that expression, he can do whatever he
    > >> > wants because that expression invokes undefined behavior.

    >
    > >> When the compiler sees that expression, it cannot be sure whether it
    > >> will be executed. It must compile the code, and if the program reaches
    > >> the point where the expression is evaluated, _then_ the behaviour is
    > >> undefined. The compiler cannot do whatever it wants. The compiler can
    > >> make the resulting code do whatever it wants.

    >
    > > What ELSE could the compiler do other than having the output be whatever
    > > he wants? I don't think you've really added to what I said.

    >
    > A non-conforming compiler could give an error message and refuse to
    > compile any program containing a^=b^=a^=b, but a conforming compiler is
    > not allowed to do so (or at least not always).


    Wrong, a conforming compiler can reject that code. The reason might be
    quite different than the expression, but it serves more like an excuse
    to reject this. For example, the compiler could claim (assuming a, b,
    int) that the source exceeds the environmental limits.

    > >> >> operator is right associative

    >
    > >> > Uh, no, it's UB.

    >
    > >> Uh, yes, ^= is right associative. The behaviour is undefined but that
    > >> does not affect parsing.

    >
    > > Well, UB is when the standard doesn't impose any requirements for the
    > > behavior of the implementation.

    >
    > Yes, but to get to the part where the standard says the behaviour is
    > undefined you need to have already parsed the expression. I can't give an
    > exact chapter and verse, but can you explain how you can determine that
    > the behaviour is undefined without parsing?


    If I understand, what you're saying is that the semantics of something
    are not affected by UB, well that's wrong I believe. ^= doesn't need
    to be anything meaningful after the first UB in source code.
    , Nov 15, 2008
    #15
  16. On Sat, 15 Nov 2008 06:19:14 -0800, vippstar wrote:
    > On Nov 15, 4:04 pm, Harald van Dijk <> wrote:
    >> A non-conforming compiler could give an error message and refuse to
    >> compile any program containing a^=b^=a^=b, but a conforming compiler is
    >> not allowed to do so (or at least not always).

    >
    > Wrong, a conforming compiler can reject that code. The reason might be
    > quite different than the expression, but it serves more like an excuse
    > to reject this. For example, the compiler could claim (assuming a, b,
    > int) that the source exceeds the environmental limits.


    Heh, that's nasty. I suppose it has to also reject a^=b^=c^=d, then, to
    cover up its lie? I can't think of a limit right now that a^=b^=a^=b might
    exceed that a^=b^=c^=d doesn't, and if you can, then I can try to come up
    with another valid example that also exceeds that limit. :)

    >> >> Uh, yes, ^= is right associative. The behaviour is undefined but
    >> >> that does not affect parsing.

    >>
    >> > Well, UB is when the standard doesn't impose any requirements for the
    >> > behavior of the implementation.

    >>
    >> Yes, but to get to the part where the standard says the behaviour is
    >> undefined you need to have already parsed the expression. I can't give
    >> an exact chapter and verse, but can you explain how you can determine
    >> that the behaviour is undefined without parsing?

    >
    > If I understand, what you're saying is that the semantics of something
    > are not affected by UB, well that's wrong I believe.


    Yes, that is wrong, and no, that is not what I'm saying.

    > ^= doesn't need to
    > be anything meaningful after the first UB in source code.


    To determine that a^=b^=a^=b modifies a at all, you need to already have
    determined that this is an assignment-expression with only a as its left
    operand. In other words, that it is equivalent to a^=(b^=(a^=b)) instead
    of ((a^=b)^=a)^=b. The latter is simply a constraint violation and
    attempts to modify a only once: the other ^= operators attempts to modify
    the result of an assignment.
    Harald van Dijk, Nov 15, 2008
    #16
  17. Guest

    On Nov 15, 5:01 pm, Harald van D©¦k <> wrote:
    > On Sat, 15 Nov 2008 06:19:14 -0800, vippstar wrote:
    > > On Nov 15, 4:04 pm, Harald van D©¦k <> wrote:
    > >> A non-conforming compiler could give an error message and refuse to
    > >> compile any program containing a^=b^=a^=b, but a conforming compiler is
    > >> not allowed to do so (or at least not always).

    >
    > > Wrong, a conforming compiler can reject that code. The reason might be
    > > quite different than the expression, but it serves more like an excuse
    > > to reject this. For example, the compiler could claim (assuming a, b,
    > > int) that the source exceeds the environmental limits.

    >
    > Heh, that's nasty. I suppose it has to also reject a^=b^=c^=d, then, to
    > cover up its lie? I can't think of a limit right now that a^=b^=a^=b might
    > exceed that a^=b^=c^=d doesn't, and if you can, then I can try to come up
    > with another valid example that also exceeds that limit. :)


    There's no need for that, a conforming compiler can also reject
    a^=b^=c^=d for the same reason.
    Also, a compiler doesn't have to cover up its lies as there's no such
    requirement. My point is that a conforming compiler can reject
    anything, and a compiler can output anything when UB is encountered. I
    believe that to be true, and I think the requirements the standard
    sets on an implemenations agree with those words.

    > >> >> Uh, yes, ^= is right associative. The behaviour is undefined but
    > >> >> that does not affect parsing.

    >
    > >> > Well, UB is when the standard doesn't impose any requirements for the
    > >> > behavior of the implementation.

    >
    > >> Yes, but to get to the part where the standard says the behaviour is
    > >> undefined you need to have already parsed the expression. I can't give
    > >> an exact chapter and verse, but can you explain how you can determine
    > >> that the behaviour is undefined without parsing?

    >
    > > If I understand, what you're saying is that the semantics of something
    > > are not affected by UB, well that's wrong I believe.

    >
    > Yes, that is wrong, and no, that is not what I'm saying.


    Alright then...

    > > ^= doesn't need to
    > > be anything meaningful after the first UB in source code.

    >
    > To determine that a^=b^=a^=b modifies a at all, you need to already have
    > determined that this is an assignment-expression with only a as its left
    > operand. In other words, that it is equivalent to a^=(b^=(a^=b)) instead
    > of ((a^=b)^=a)^=b. The latter is simply a constraint violation and
    > attempts to modify a only once: the other ^= operators attempts to modify
    > the result of an assignment.


    Hmm... then yes, I was wrong on the original matter.
    , Nov 15, 2008
    #17
  18. Guest

    On Nov 15, 5:56 pm, wrote:
    > On Nov 15, 2:39 pm, ""
    >
    >
    >
    > <> wrote:
    > > On Nov 15, 5:24 pm, "Joachim Schmitz" <>
    > > wrote:

    >
    > > > wrote:
    > > > > <<Be cautious, I have not written a^=b^=a^=b ; which, of course, is
    > > > > undefined. I am having some confusion with the former statement!>>

    >
    > > > > I think this expression is valid as assignment operator is evaluated
    > > > > from right to left so it is parsed as
    > > > > (a^=(b^=(a^=b)))
    > > > > above expression swaps two numbers
    > > > > please correct me if i am wrong...

    >
    > > > This is modifying 'a' twice without an intermediate sequence point ->
    > > > undefined behavoir

    >
    > > > Bye, Jojo

    >
    > > sorry,I am still not able to get it...


    > > but a=b=3 is valid
    > > Please clear my confusion...

    >
    > For the reasons I explained before. Now I have a question: How the
    > hell do you know that a = b = 3 is valid if you don't understand and
    > you're confused


    Now i am able to get it.
    I know a=b=3 is valid as i read it in my C text book but i had not
    read other undefined statement in this thread so i was confused about
    it...
    , Nov 15, 2008
    #18
  19. Guest

    On Nov 15, 7:12 pm, ""
    <> wrote:
    > I know a=b=3 is valid as i read it in my C text book but i had not
    > read other undefined statement in this thread so i was confused about
    > it..


    Which book and page?
    , Nov 15, 2008
    #19
  20. Guest

    On Nov 15, 10:35 pm, wrote:
    > On Nov 15, 7:12 pm, ""
    >
    > <> wrote:
    > > I know a=b=3 is valid as i read it in my C text book but i had not
    > > read other undefined statement in this thread so i was confused about
    > > it..

    >
    > Which book and page?


    K n R page-48...in function strcat
    2nd line is i=j=0;
    , Nov 15, 2008
    #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. aka
    Replies:
    10
    Views:
    691
  2. REH
    Replies:
    25
    Views:
    821
    Victor Bazarov
    Mar 29, 2005
  3. Mantorok Redgormor
    Replies:
    70
    Views:
    1,734
    Dan Pop
    Feb 17, 2004
  4. VK
    Replies:
    45
    Views:
    579
    Dr John Stockton
    Sep 12, 2006
  5. -Lost
    Replies:
    13
    Views:
    359
    Richard Cornford
    Jan 31, 2007
Loading...

Share This Page