# 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

2. ### Joachim SchmitzGuest

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

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
4. ### Joachim SchmitzGuest

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
5. ### maverikGuest

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
6. ### James KuyperGuest

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
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

thanks,

, Nov 15, 2008
8. ### maverikGuest

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
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

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
10. ### Harald van DÄ³kGuest

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 DÄ³k, Nov 15, 2008
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
12. ### James KuyperGuest

Harald van DÄ³k 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
13. ### Harald van DÄ³kGuest

On Sat, 15 Nov 2008 13:38:21 +0000, James Kuyper wrote:
> Harald van DÄ³k 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 DÄ³k, Nov 15, 2008
14. ### Harald van DÄ³kGuest

On Sat, 15 Nov 2008 05:37:35 -0800, vippstar wrote:
> 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.

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 DÄ³k, Nov 15, 2008
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
16. ### Harald van DÄ³kGuest

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.

>> >> 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 DÄ³k, Nov 15, 2008
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
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
it...

, Nov 15, 2008
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
> it..

Which book and page?

, Nov 15, 2008
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
> > it..

>
> Which book and page?

K n R page-48...in function strcat
2nd line is i=j=0;

, Nov 15, 2008