Velocity Reviews > x=r=y; // With r volatile. Is r read?

# x=r=y; // With r volatile. Is r read?

lawrence.jones@siemens.com
Guest
Posts: n/a

 03-08-2011
Jens <(E-Mail Removed)> wrote:
>
> Exactly. The draft of C1X even has a footnote (in assignment
> operators) to make the situation in question explicit:
>
> C1X> The implementation is permitted to read the object to determine
> the value but is not
> C1X> required to, even when the object has volatile-qualified type.

Gee, what a coincidence!
--
Larry Jones

Another casualty of applied metaphysics. -- Hobbes

Francois Grieu
Guest
Posts: n/a

 03-08-2011
> On Mar 8, 7:18 am, Kenneth Brody <(E-Mail Removed)> wrote:
>> On 3/7/2011 12:00 PM, Mark Bluemel wrote:
>>
>>
>>
>>> On 03/07/2011 04:41 PM, Francois Grieu wrote:
>>>> On 07/03/2011 17:33, Mark Bluemel wrote:
>>>>> On 03/07/2011 04:05 PM, Francois Grieu
>>>>>> Hi, the subject sums it all.

>>
>>>>>> extern volatile unsigned r;
>>>>>> unsigned x,y;

>>
>>>>>> void test(void)
>>>>>> {
>>>>>> x=r=y;
>>>>>> }

>> [...]
>>>>> so there is no need for r to be read.

>>
>>>> I'm unsure of that, and of if "no need" translates to "no read".
>>>> My problem boils down to: is the value of (r=y)
>>>> - the value read from y (that gets written into r).
>>>> - the value read from r (after?) writing the value of y into r.
>>>> - any of the above.
>>>> - other..

>>
>>> http://www.open-std.org/jtc1/sc22/wg...docs/n1256.pdf
>>> 6.5.16 paragraph 3
>>> .... An assignment expression has the value of the left operand after the
>>> assignment ....

>>
>>> I see no mention of other operations after the assignment.

>>
>> Consider the fact that, with a volatile, the "value of the left operand
>> after the assignment" might not necessarily be the value that was just
>> assigned to it.
>>

>
> Would this be because the assignment produces a side effect?

A common example is a register r where some (or all) bits are always
read as 0, regardless of what's written to.

Francois Grieu

Guest
Posts: n/a

 03-08-2011
On Mar 8, 9:00*am, Francois Grieu <(E-Mail Removed)> wrote:
> On 08/03/2011 17:23, Chad wrote:
>
>
>
> > On Mar 8, 7:18 am, Kenneth Brody <(E-Mail Removed)> wrote:
> >> On 3/7/2011 12:00 PM, Mark Bluemel wrote:

>
> >>> On 03/07/2011 04:41 PM, Francois Grieu wrote:
> >>>> On 07/03/2011 17:33, Mark Bluemel wrote:
> >>>>> On 03/07/2011 04:05 PM, Francois Grieu
> >>>>>> Hi, the subject sums it all.

>
> >>>>>> extern volatile unsigned r;
> >>>>>> unsigned x,y;

>
> >>>>>> void test(void)
> >>>>>> {
> >>>>>> x=r=y;
> >>>>>> }
> >> [...]
> >>>>> so there is no need for r to be read.

>
> >>>> I'm unsure of that, and of if "no need" translates to "no read".
> >>>> My problem boils down to: is the value of (r=y)
> >>>> - the value read from y (that gets written into r).
> >>>> - the value read from r (after?) writing the value of y into r.
> >>>> - any of the above.
> >>>> - other..

>
> >>>http://www.open-std.org/jtc1/sc22/wg...docs/n1256.pdf
> >>> 6.5.16 paragraph 3
> >>> .... An assignment expression has the value of the left operand afterthe
> >>> assignment ....

>
> >>> I see no mention of other operations after the assignment.

>
> >> Consider the fact that, with a volatile, the "value of the left operand
> >> after the assignment" might not necessarily be the value that was just
> >> assigned to it.

>
> > Would this be because the assignment produces a side effect?

>
> A common example is a register r where some (or all) bits are always
> read as 0, regardless of what's written to.
>

I was think of something like the following....

#include <stdio.h>

int main(void)
{
int a = 5;
int b = 9;

int k = a++ + ++b;

printf("The value of k is: %d\n", k);
printf("a = %d and b = %d\n", a, b);
return 0;
}
[cdalten@localhost oakland]\$ gcc -Wall -Wextra -Wshadow side.c -o side
[cdalten@localhost oakland]\$ ./side
The value of k is: 15
a = 6 and b = 10
[cdalten@localhost oakland]\$

This is how I would attempt to explain the example...

In this case, the value of 'b' is incremented by 1. Then this value,
which is now 10, is added the value of 'a' (which is still 5), to
produce a value of 16. The side effect would be the result of applying
the postincrement operator to 'a'. The result of this side effect is
that the value of 'a' is increased by one. Which would happen after
the sequence point?

Or something along those lines. I'm pretty sure the regulars will
correct me.

Guest
Posts: n/a

 03-08-2011
On Mar 8, 10:03*am, Chad <(E-Mail Removed)> wrote:
> On Mar 8, 9:00*am, Francois Grieu <(E-Mail Removed)> wrote:
>
>
>
> > On 08/03/2011 17:23, Chad wrote:

>
> > > On Mar 8, 7:18 am, Kenneth Brody <(E-Mail Removed)> wrote:
> > >> On 3/7/2011 12:00 PM, Mark Bluemel wrote:

>
> > >>> On 03/07/2011 04:41 PM, Francois Grieu wrote:
> > >>>> On 07/03/2011 17:33, Mark Bluemel wrote:
> > >>>>> On 03/07/2011 04:05 PM, Francois Grieu
> > >>>>>> Hi, the subject sums it all.

>
> > >>>>>> extern volatile unsigned r;
> > >>>>>> unsigned x,y;

>
> > >>>>>> void test(void)
> > >>>>>> {
> > >>>>>> x=r=y;
> > >>>>>> }
> > >> [...]
> > >>>>> so there is no need for r to be read.

>
> > >>>> I'm unsure of that, and of if "no need" translates to "no read".
> > >>>> My problem boils down to: is the value of (r=y)
> > >>>> - the value read from y (that gets written into r).
> > >>>> - the value read from r (after?) writing the value of y into r.
> > >>>> - any of the above.
> > >>>> - other..

>
> > >>>http://www.open-std.org/jtc1/sc22/wg...docs/n1256.pdf
> > >>> 6.5.16 paragraph 3
> > >>> .... An assignment expression has the value of the left operand after the
> > >>> assignment ....

>
> > >>> I see no mention of other operations after the assignment.

>
> > >> Consider the fact that, with a volatile, the "value of the left operand
> > >> after the assignment" might not necessarily be the value that was just
> > >> assigned to it.

>
> > > Would this be because the assignment produces a side effect?

>
> > A common example is a register r where some (or all) bits are always
> > read as 0, regardless of what's written to.

>
> I was think of something like the following....
>
> #include <stdio.h>
>
> int main(void)
> {
> * int a = 5;
> * int b = 9;
>
> * int k = a++ + ++b;
>
> * printf("The value of k is: %d\n", k);
> * printf("a = %d and b = %d\n", a, b);
> * return 0;}
>
> [cdalten@localhost oakland]\$ gcc -Wall -Wextra -Wshadow side.c -o side
> [cdalten@localhost oakland]\$ ./side
> The value of k is: 15
> a = 6 and b = 10
> [cdalten@localhost oakland]\$
>
> This is how I would attempt to explain the example...
>
> In this case, the value of 'b' is incremented by 1. Then this value,
> which is now 10, is added the value of 'a' (which is still 5), to
> produce a value of 16. The side effect would be the result of applying
> the postincrement operator to 'a'. The result of this side effect is
> that the value of 'a' is increased by one. Which would happen after
> the sequence point?
>
> Or something along those lines. I'm pretty sure the regulars will
> correct me.
>

The part I'm kind of fuzzy about is the ++b

in

int k = a++ + ++b;

The result of the preincrement operator to (applied) b is also a side
effect. However, I think this side effect is applied before the
statement completes. Ie, both b in incremented by one and the side
effect is applied to b. Whereas side effect of a++ is applied *after*
the statement completes.

Keith Thompson
Guest
Posts: n/a

 03-08-2011
[...]
> The part I'm kind of fuzzy about is the ++b
>
> in
>
> int k = a++ + ++b;
>
> The result of the preincrement operator to (applied) b is also a side
> effect. However, I think this side effect is applied before the
> statement completes. Ie, both b in incremented by one and the side
> effect is applied to b. Whereas side effect of a++ is applied *after*
> the statement completes.

The standard defines the behavior of ++b:

The value of the operand of the prefix ++ operator is
incremented. The result is the new value of the operand
after incrementation. The expression ++E is equivalent to
(E+=1). See the discussions of additive operators and compound
assignment for information on constraints, types, side effects,
and conversions and the effects of operations on pointers.

For both a++ and ++b, the side effect occurs some time between the
preceding and following sequence points.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Spiros Bousbouras
Guest
Posts: n/a

 03-08-2011
On Tue, 8 Mar 2011 08:23:01 -0800 (PST)
> On Mar 8, 7:18 am, Kenneth Brody <(E-Mail Removed)> wrote:
> > Consider the fact that, with a volatile, the "value of the left operand
> > after the assignment" might not necessarily be the value that was just
> > assigned to it.

>
> Would this be because the assignment produces a side effect?

No , it would be because with a volatile , an outside agent outside
the control of the C programme can modify the value of the variable.
With non volatiles this is not allowed to happen.

Keith Thompson
Guest
Posts: n/a

 03-08-2011
Kenneth Brody <(E-Mail Removed)> writes:
[...]
> Despite the fact that we are using the value of "a++" after the increment,
> and "++b" before the increment, the result is indistinguishable from the
> other way around. (However, there may be a problem with this implementation
> for values of a==INT_MAX and b<0 due to the overflow in "a++". I leave that
> discussion to those who are more versed in the intricacies of the Standard
> than I am.)

If a==INT_MAX, then the behavior of "a++" is undefined, which makes
the behavior of the entire statement undefined. To put it another
way, the compiler is free to generate code based on the assumption
that it *won't* overflow.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Spiros Bousbouras
Guest
Posts: n/a

 03-08-2011
On Tue, 08 Mar 2011 14:58:41 -0500
Kenneth Brody <(E-Mail Removed)> wrote:
> On 3/8/2011 1:09 PM, Chad wrote:
> [...]
> > The part I'm kind of fuzzy about is the ++b
> >
> > in
> >
> > int k = a++ + ++b;
> >
> > The result of the preincrement operator to (applied) b is also a side
> > effect. However, I think this side effect is applied before the
> > statement completes. Ie, both b in incremented by one and the side
> > effect is applied to b. Whereas side effect of a++ is applied *after*
> > the statement completes.

>
> No. Both the increments of a and of b are guaranteed to take place before
> the statement completes. (Or, more technically, before the next "sequence
> point".) When, exactly, during the execution of the statement, the
> increments take place is not specified by the Standard.
>
> However, the meaning of "a++" is "the value of a before the increment", and
> "++b" is "the value of b after the increment". However, that does not
> necessarily mean that "b" actually has been incremented by the time the
> value of "++b" is used, nor that "a" won't be incremented before the value
>
> In other words, this pseudo-code is a perfectly valid implementation of the
> above code:
>
> ; extern int a,b;
> ; int k = a++ + ++b;
>
> incr k
> incr a
> incr b
>
> In fact, I believe this implementation is just as valid:
>
> incr a
> incr b
>
> Despite the fact that we are using the value of "a++" after the increment,
> and "++b" before the increment, the result is indistinguishable from the
> other way around. (However, there may be a problem with this implementation
> for values of a==INT_MAX and b<0 due to the overflow in "a++".

If a==INT_MAX then a++ produces undefined behavior so all
implementations are valid.

lawrence.jones@siemens.com
Guest
Posts: n/a

 03-08-2011
Kenneth Brody <(E-Mail Removed)> wrote:
>
> Consider the fact that, with a volatile, the "value of the left operand
> after the assignment" might not necessarily be the value that was just
> assigned to it.
>
> But, apparently that description was ambiguous, and the latest draft of the
> Standard (see elsethread) make it clear that it's implementation defined.

Unspecified, not implementation defined.
--
Larry Jones

These child psychology books we bought were such a waste of money.
-- Calvin's Mom

Tim Rentsch
Guest
Posts: n/a

 03-11-2011
Keith Thompson <(E-Mail Removed)> writes:

> Kenneth Brody <(E-Mail Removed)> writes:
> [...]
>> Despite the fact that we are using the value of "a++" after the increment,
>> and "++b" before the increment, the result is indistinguishable from the
>> other way around. (However, there may be a problem with this implementation
>> for values of a==INT_MAX and b<0 due to the overflow in "a++". I leave that
>> discussion to those who are more versed in the intricacies of the Standard
>> than I am.)

>
> If a==INT_MAX, then the behavior of "a++" is undefined, which makes
> the behavior of the entire statement undefined. To put it another
> way, the compiler is free to generate code based on the assumption
> that it *won't* overflow.

The compiler _might_ be free to do that, depending on if and how
the implementation chooses to define the behavior on overflow,
which the implementation is at liberty to do however it wishes.