This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Assignment operator


Mike Stump writes:
 > >  > If GNU C accesses it, that is a bug.  
 > >  
 > > Well, unfortunately, it is not a bug, it is a feature, which is in
 > > accordance to the current and future ANSI C standard. On the other
 > > hand, it would be in accordance with the standard if it did not
 > > access the LHS. The standard leaves it to the implementor. This is
 > > actually independent of the possible qualifiers of the LHS.
 > 
 > I am afraid you lost me on that one.  If you meant to say that GNU C
 > is allowed to access it by the standard, then we will simply have
 > disagree.  I found the C standard to be exceptionally clear on this
 > point.

Believe me, if GNU C wasn't allowed to re-read the LHS, I wouldn't
have started the thread. I thought it was a bug, then I've been told
that the standard *forces* gcc to re-read it, stupid, and, by the way, 
unqualified personnel should not use volatile.

The standard, as it turns out, actually lets gcc to do whatever it 
pleases. 

Here's part of the reply I got from Thomas MacDonald <tam@sgi.com>
in the C Standard Committe. (You can have the full story, if you 
want it.)
 
 : A careful reading of the C Standard clearly does *not* require
 : re-reading the lvalue for a statement such as:
 : 
 :    a = b = c;
 : 
 : It is permitted, but not required.  Section 5.1.2.3 of C9X states in
 : part:
 : 
 :        5.1.2.3  Program execution
 : 
 :        [#1]   The   semantic  descriptions  in  this  International
 :        Standard describe the behavior of  an  abstract  machine  in
 :        which issues of optimization are irrelevant.
 : 
 :        [#2]  Accessing  a  volatile  object,  modifying  an object,
 :        modifying a file, or calling a function  that  does  any  of
 :        those  operations are all side effects,11) which are changes
 :        in the state of the execution environment.  Evaluation of an
 :        expression  may  produce side effects.  At certain specified
 :        points in the execution sequence called sequence points, all
 :        side  effects  of previous evaluations shall be complete and
 :        no side effects of subsequent evaluations shall  have  taken
 :        place.   (A summary of the sequence points is given in annex
 :        C.)
 : 
 : The side-effect of accessing a volatile object is not guaranteed to be
 : complete until the next sequence point.  Therefore, it is simply not
 : true that a volatile object must be re-read in between two side-effects
 : to obtain its value.  The argument that "the value of a volatile
 : left-hand side can only be retrieved by re-reading it" is false, and
 : cannot be justified by *only* reading the description of assignment
 : operators.  The C standard must be read as a whole to be understood.
 : 
 : If certain compiler writes are using such arguments then, in my opinon,
 : they are wrong.
 : 
 : Again, an implementation is allowed to re-read volatile objects but not
 : required to re-read volatile objects in-between two adjacent sequence
 : points.  This latitude is explicitly granted in the C Standard.

This is the basis of the whole discussion. 
 
 > Please cite the standard where it guarantees that *dst is different
 > from *src.  I wasn't aware of that requirement.  If they fail to be
 > different, then the optimizer is free to optimize *src into *dst.

Yes, you are right. 
 
 > Oh, sorry, I misunderstood your point, my fault.  I was thinking *b.
 > No b should not be refetched.  For the same reason that *foo() should
 > not call foo twice.  I tried to find the wording in the paper, but
 > didn't locate it.  If it fails to be there, this is a bug in the
 > standard.  The wording would be something like, address
 > expressions are only calculated once.

You are probably right, however, *foo() and *b are not the same.
In an other reply Thomas MacDonald wrote this to me:

 : To further clarify, in the following statement:
 : 
 :    a = b + b;
 : 
 : The variable 'b' does *not* have to be accessed from memory twice (even
 : if it is declared 'volatile') because volatile objects are only stable
 : at sequence point boundaries.

Now calling foo() is a sequence point in itself. Dereferencing b is
not. 

  x = *foo() + *foo();
  
guarantees two calls to foo() and two fetches from the addresses 
returned.

  x = *b + *b;
  
does not guarantee that.

Therefore, in a = *b = c; dereferencing b once or twice, as far as
I can tell, is not forbidden by the standard. In the case of 
a = *foo() = c; calling foo() is a sequence point and thus can neither 
be eliminated nor duplicated - foo() must be called *exactly* once.

 > I already spoke to the point of volatile and C, no need to repeat it.
 > In the above, I was talking about the semantics that gcc will
 > implement and the semantics required by ANSI C++.

OK, I has been and is still talking about C, strictly C. No C++
whatsoever. They, by the way, seem to be *very* different languages
with regards to assignments and volatile objects.

 > > What's even more scary is that it has every right to do so.
 > 
 > Right.
 > 
 > > With or without volatile qualifiers, actually.
 > 
 > Well, with volatile, in C, it can't access.  For C++ and volatile, I
 > agree.

If you believe Thomas MacDonald, you should accept that a conforming
C compiler can terminate the while( *a++ = *b++ ); loop on either
*a or *b even if they are volatile. This is what the whole thread is 
about. Currently gcc terminates on *b if *a is not volatile, on *a if
it is. Egcs terminates on *a regardless of its qualifier.
 
 > > You mean it is guaranteed by the standard ?
 > 
 > I'll go out on a limb, and say sure.  
 
I've found the part in the C standard that specifies that for

  x = a;

x will be written exactly once. I did not find a part which would 
ban a read of x or more than one reads of a.

 > You might be able to nit pick, and claim the exact wording doesn't say
 > that in exacting detail, but I would claim this is what the words
 > written mean.

Probably. Would be logical. Just like using the value written instead
of a re-reading it in an assignment :-)
 
 > >-)  We agree.  I have fun with this stuff, I hope you are...

I have fun in arguing and I'm frustrated by the behaviour of the
compiler :-( 

Regards,

Zoltan


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]