[gimple] assignments to volatile

Mike Stump mikestump@comcast.net
Thu Jun 24 17:05:00 GMT 2010


On Jun 24, 2010, at 1:04 AM, Nathan Sidwell wrote:
> On 06/23/10 19:36, Mike Stump wrote:
>> C++ says:
> 
> C and C++ differ in their cast-to-void behaviour.  In particular, in C++
>  (void)obj;
> does not cause a read of obj, because no lvalue->rvalue decay occurs.  This is very confusing for volatiles and incompatible with established C semantics.  As such G++ will cause a read of a volatile scalar obj in these cases.

Yeah, this was one of the later changes that I groaned over when it went in, I wish the C and C++ standards people were on the same page.  If they are to differ, I would not be against just making the construct an error, to prohibit people from making any use of a semantic that isn't the same in both languages.  I know the status quo is to just conform to the C semantic, and I didn't argue or object to that; it's just an unfortunate position to be in.  However, since we went in that direction, I wish people would formulate a change for the C++ language consistent with that and get that in, say, in the name of C compatibility.

> In C++ the result of an assignment is an lvalue.  It is not in C.
> 
>> You can't just willy nilly change this:
>> 
>> int i, j, k;
>> void foo(int&j) {
>>   foo(i = k);
>> }
>> 
>> can sense if you get it right or not.  Add a volatile on i, and you discover, you can't just change this as you see fit, in particular, not in the way you all seem to want, which is just plain wrong.
> 
> I do not know what you are saying here.  Making (just) i volatile will render your code example ill-formed.

Sorry for not expounding.  I thought it would be obvious I was talking about well formed code...  First case would be something like:

volatile int i, j, k;
volatile int vi;
void foo(volatile int& j) {
  foo(i = k);
}

here, we need to bind j to the address of i.  The second case is something like:

volatile int i, j, k;
volatile int vi;
void foo(int j) {
  foo(i = k);
}

where the value passed to foo is the value read from i, and i being volatile, would mean a read of i.

>> Further, C says:
>> 
>>   An assignment expression has the value of the left operand after the assignment
>> 
>> Now, this is pretty plain, the value is the left operand.  They choose this wording as they didn't want the return value to be a modifiable lvalue.  I concede there is enough wiggle room here to confuse users and give implementors enough latitude to try and claim they are following the standard, but really, the return value is the valuer of the left operand, if it weren't, the standard would not say it was.  It could have said, the value is the value that was stored in the left operand, or the value is the right operand after conversion to the type of the left operand, or a host of other possibilities.
> 
> Are you saying that in C, both
> 
>  (void)obj;
> and
>  (void)(obj = value);
> 
> should behave the same wrt the behaviour of reads from a volatile obj?  I thought there was consensus that they should not.

Technically, I was arguing against the dropping of the re-read of vobj in the  a = vobj = c; case.  I believe doing so would cause g++ to violate the C++ language standard.



More information about the Gcc-patches mailing list