Velocity Reviews > sequence points in subexpressions

# sequence points in subexpressions

amit.codename13@gmail.com
Guest
Posts: n/a

 12-13-2009
Does the statement given below invoke undefined behavior?
i = (i, i++, i) + 1;

I am almost convinced that it does not because of the following
reasons

1> the RHS must be evaluated before a value can be stored in i
2> evaluation of RHS does not invoke UB due to the sequence points
introduced by comma operator

Correct me if i an wrong!

Thanks

amit.codename13@gmail.com
Guest
Posts: n/a

 12-13-2009
On Dec 13, 10:29*am, Richard <(E-Mail Removed)> wrote:
> "(E-Mail Removed)" <(E-Mail Removed)> writes:
> > Does the statement given below invoke undefined behavior?
> > i = (i, i++, i) + 1;

>
> > I am almost convinced that it does not because of the following
> > reasons

>
> > 1> the RHS must be evaluated before a value can be stored in i
> > 2> evaluation of RHS does not invoke UB due to the sequence points
> > introduced by comma operator

>
> > Correct me if i an wrong!

>
> > Thanks

>
> What do you think the answer is?
>
> i=i+2 ?
>
> --
> "Avoid hyperbole at all costs, its the most destructive argument on
> the planet" - Mark McIntyre in comp.lang.c

I am sure that it's well defined.

I am quoting someone's comment/view on that statement.
> Yes the sequence point after i++ completes all side effects before it, but there is nothing that > stops the assignment side effect overlapping with the side effect of i++. The underlying problem > is that the side effect of an assignment is not specified to happen after or before the
> evaluation of both operands of the assignment, and so sequence points cannot do anything with
> regard to protecting this: Sequence points induce a partial order: Just because there is a
> sequence point after and before i++ doesn't mean all side effects are sequenced with regard to
> it.

I was trying to comprehend it.
I am not *100%* sure that what he said is wrong.
So any comments on it(the comment)?

mohangupta13
Guest
Posts: n/a

 12-13-2009
On Dec 13, 5:05*pm, Richard <(E-Mail Removed)> wrote:
> pete <(E-Mail Removed)> writes:
> > (E-Mail Removed) wrote:
> >> Does the statement given below invoke undefined behavior?
> >> i = (i, i++, i) + 1;

>
> >> I am almost convinced that it does not because of the following
> >> reasons

>
> >> 1> the RHS must be evaluated before a value can be stored in i

>
> > You would think so but,
> > the evaluation of an expression also includes side effects,
> > and the side effects of the evaluation of the right operand
> > do not have to occur
> > before the assignment operation on the left operand.

>
> What side affects would you expect from the right hand side, keeping in
> mind the sequence points?
>
> --
> "Avoid hyperbole at all costs, its the most destructive argument on
> the planet" - Mark McIntyre in comp.lang.c

say whether the above statement is actually UD or not ? I am not able
to get this from the above comments .

Thanks
Mohan

Seebs
Guest
Posts: n/a

 12-13-2009
On 2009-12-13, mohangupta13 <(E-Mail Removed)> wrote:
> With due regard to everyone's comments , can anyone please explicitly
> say whether the above statement is actually UD or not ? I am not able
> to get this from the above comments .

I am honestly not sure.

I think it is, but... I don't know. Here's the case that convinced me:

a[i] = (1, i++, 1);

It seems clear to me that there's a real-world risk that the evaluation of
i on the left is at risk of occurring during the evaluation of the RHS.
So I don't think there's a sequence point between the sides.

More importantly:
1. You don't need to do that.
2. Even if it's not undefined behavior, it's the kind of case where compilers
might have unexpected bugs.
3. So don't do that, then. Just write out what you mean.

In most of the "interesting" edge cases, the right answer is not to go there.

-s
--
Copyright 2009, all wrongs reversed. Peter Seebach / http://www.velocityreviews.com/forums/(E-Mail Removed)
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!

Nick
Guest
Posts: n/a

 12-13-2009
mohangupta13 <(E-Mail Removed)> writes:

> On Dec 13, 5:05Â*pm, Richard <(E-Mail Removed)> wrote:
>> pete <(E-Mail Removed)> writes:
>> > (E-Mail Removed) wrote:
>> >> Does the statement given below invoke undefined behavior?
>> >> i = (i, i++, i) + 1;

>>
>> >> I am almost convinced that it does not because of the following
>> >> reasons

>>
>> >> 1> the RHS must be evaluated before a value can be stored in i

>>
>> > You would think so but,
>> > the evaluation of an expression also includes side effects,
>> > and the side effects of the evaluation of the right operand
>> > do not have to occur
>> > before the assignment operation on the left operand.

>>
>> What side affects would you expect from the right hand side, keeping in
>> mind the sequence points?
>>

>
> With due regard to everyone's comments , can anyone please explicitly
> say whether the above statement is actually UD or not ? I am not able
> to get this from the above comments .

doesn't look the sort of thing that might be produced by computer
generated code, and it doesn't look the thing you'd actually want to
write into a program. If it's that borderline and you'd never need it,
why does it actually matter, other than as a sort of C language sudoku.
--
Online waterways route planner: http://canalplan.org.uk
development version: http://canalplan.eu

Kenny McCormack
Guest
Posts: n/a

 12-13-2009
In article <(E-Mail Removed)>,
Nick <(E-Mail Removed)> wrote:
....
>doesn't look the sort of thing that might be produced by computer
>generated code, and it doesn't look the thing you'd actually want to
>write into a program. If it's that borderline and you'd never need it,
>why does it actually matter, other than as a sort of C language sudoku.

Indeed. Well put. ITA.

But the point is that that is precisely the stock-in-trade of this
newsgroup. As I have shown many times, it is not possible to post
anything to this newsgroup, that will meet the generally accepted
standards of "appropriateness", that is not either a) a topicality flame
(gotta love them!) or b) language lawyering, of the type that is of no
interest to the vast majority of working C programmers.

Your post hits the nail on the head as to the sort of thing that people
like Kiki, et al, just salivate over, but the rest of us find dull and
uninteresting at best, and downright offensive at worst.

Flash Gordon
Guest
Posts: n/a

 12-13-2009
Seebs wrote:
> On 2009-12-13, mohangupta13 <(E-Mail Removed)> wrote:
>> With due regard to everyone's comments , can anyone please explicitly
>> say whether the above statement is actually UD or not ? I am not able
>> to get this from the above comments .

For context, the statement was
i = (i, i++, i) + 1;

> I am honestly not sure.
>
> I think it is, but... I don't know.

I think it isn't UB.

> Here's the case that convinced me:
>
> a[i] = (1, i++, 1);
>
> It seems clear to me that there's a real-world risk that the evaluation of
> i on the left is at risk of occurring during the evaluation of the RHS.
> So I don't think there's a sequence point between the sides.

That example is different because i is used on the left to determine the
object to be stored, where as in the original it is merely the object in
which the result will be stored.

> More importantly:
> 1. You don't need to do that.
> 2. Even if it's not undefined behavior, it's the kind of case where compilers
> might have unexpected bugs.
> 3. So don't do that, then. Just write out what you mean.
>
> In most of the "interesting" edge cases, the right answer is not to go there.

That I definitely agree with. I would reject any code like this I came
across in a code review.
--
Flash Gordon

Guest
Posts: n/a

 12-13-2009
On Dec 13, 11:20*am, Flash Gordon <(E-Mail Removed)> wrote:
> Seebs wrote:
> > On 2009-12-13, mohangupta13 <(E-Mail Removed)> wrote:
> >> With due regard to everyone's comments , can anyone please explicitly
> >> say whether the above statement is actually UD or not ? I am not able
> >> to get this from the above comments .

>
> For context, the statement was
> * * i = (i, i++, i) + 1;
>
> > I am honestly not sure.

>
> > I think it is, but... I don't know.

>
> I think it isn't UB.
>
> > *Here's the case that convinced me:

>
> > * *a[i] = (1, i++, 1);

>
> > It seems clear to me that there's a real-world risk that the evaluation of
> > i on the left is at risk of occurring during the evaluation of the RHS.
> > So I don't think there's a sequence point between the sides.

>
> That example is different because i is used on the left to determine the
> object to be stored, where as in the original it is merely the object in
> which the result will be stored.
>

Why wouldn't the result get store in a[i] = (1, i++, 1); ?

Beej Jorgensen
Guest
Posts: n/a

 12-13-2009
On 12/12/2009 09:09 PM, (E-Mail Removed) wrote:
> Does the statement given below invoke undefined behavior?
> i = (i, i++, i) + 1;

I think these are the sequence points:

i = (i , i++ , i) + 1 ;
1 2 3

(1 and 2 at the end of the first operand to a comma operator, and 3 at
the end of a full expression.) So I believe what we have is this:

i [i == 0, let's say]
[sequence point 1]
i++ [i == 1 by the next sequence point]
[sequence point 2]
i = i + 1 [i == 2 by the next sequence point]
[sequence point 3]

I don't see anything here that violates C99 6.5p2, so I'm going to bet
that it's OK. gcc offers no applicable complaints* at full-warnings,
and outputs 2 in the above example.

(And I'd like to buy insurance on that bet--I'm pushing the bounds of my
knowledge, here.)

-Beej

* gcc does warn that the leftmost i in (i, i++, i) has no effect.

James Dow Allen
Guest
Posts: n/a

 12-13-2009
On Dec 14, 2:20*am, Flash Gordon <(E-Mail Removed)> wrote:
> Seebs wrote:
> > I think it is UB.

> I think it isn't UB.

I'm not sure. In the simple case:
i = (1, i++, i) + 1;
It may be hard to imagine how the C system
could go wrong, but one might be able to imagine
some cache-speeding trick that assumes it
won't encounter this code (or can do what it wants
with it, if marked UB in The Standard).

For those who think commas are permitted, what about:
*(p += i, ++i, p += i) = j++, ++j, j;
No problem right?
The commas at left separate left-side sequence points,
and commas at right separate (order) a different
set of sequence points. We end up, in effect with
i += 1, *(p += i+i-1) = j += 2;

What do we know about *which* sequence points are
reached first, right-side vs left-side, or can they
be interelaved?

*(p += i, ++i, p += i) = i++, ++i, i;
Definitely UB-lookingish.

> > In most of the "interesting" edge cases, the right answer is not to go there.

> .
> That I definitely agree with. I would reject any code like this I came
> across in a code review.

While certainly this code would be rejected,
it *is* good to look at border cases.

On Dec 13, 9:30 pm, Nick <(E-Mail Removed)> wrote:
> doesn't look the sort of thing that might be produced by computer
> generated code, and it doesn't look the thing you'd actually want to
> write into a program. If it's that borderline and you'd never need it,
> why does it actually matter, other than as a sort of C language sudoku.

I argued much like this 5 weeks back in a somewhat similar thread and
was rebuked. And the old thread was the same old silly expression
designed
to provoke UB, while OP's query *does* represent a defining corner-
case.

James Dow Allen