On Aug 21, 2014, at 4:22 AM, Richard Biener <richard.guent...@gmail.com> wrote:
> I still say we need to solve the issue at language level - that is,
> try to figure out what the language standard says about
> 
> volatile struct X x, y;

> x = y;

The definition of x = y doesn’t change wrt volatile above.  See below for the 
semantic of x = y;  What this does is it makes the members of x and y volatile:

       [#7] EXAMPLE 2 In:                                           |

               struct s { int i; const int ci; };
               struct s s;
               const struct s cs;
               volatile struct s vs;

       the various members have the types:                          |

               s.i     int
               s.ci    const int
               cs.i    const int
               cs.ci   const int
               vs.i    volatile int
               vs.ci   volatile const int

> or about
> 
> struct X { volatile int x; } x, y;
> 
> x = y;

So, what the C99 standard[1] says is that memcpy copies n characters from one 
to the other, leaving unspecified the order of the copy.  C++98 reuses by 
reference those semantics.  Of course, there are quite a few memcpy 
implementations that don’t do that.

For x = y, in C++98, it is defined like so:

8 The implicitly-defined copy constructor for class X performs a member-
  wise  copy of its subobjects.  The order of copying is the same as the
  order of initialization of bases and members in  a  user-defined  con-
  structor  (see  _class.base.init_).   Each  subobject is copied in the
  manner appropriate to its type

which means a volatile int member translates to volatile SI read/write as 
appropriate, or put another way, one can’t use memcpy for it.  Now, that isn’t 
to say that we can’t change the language standard or improve it with different 
semantics.

For C99:

       [#2] In simple  assignment  (=),  the  value  of  the  right
       operand   is   converted  to  the  type  of  the  assignment
       expression and replaces  the  value  stored  in  the  object
       designated by the left operand.

which I’d claim isn’t exactly clear and precise.  Clearly what they were 
thinking was:

       36)Thus,  for   example,   structure   assignment   may   be             
                                 
          implemented element-at-a-time or via memcpy.                          
                                 

left not exactly well defined is the case of volatile.  Reasonable people would 
say that volatile semantics are likely the same as C++98 (also, C++ was mostly 
just noting what we thought the C standard said in the first place).

I don’t keep up on DRs that might explicitly cover details, so I’d defer those 
those if any.

> I expect that most structs have volatile for a bogus reason
> anyway and we slow down and enlarge code for no good reason.

Yes, I suspect if we put in code to handle volatile members better, that no 
code will care.  Why, cause no one has asked for those semantics, no code 
depends upon those semantics.  Though, in time, some code might care.

> So - why bother fixing this?  ISTR reading in the C standard
> that structure assignments are expected to compile to memcpy.

Your ISTR is quoted for you above.  That wording isn’t a prescription of 
semantics.  It is an observation that there are some situations where the 
implementation may use memcpy.

In C99, sig_atomic_t defines when something is lock free, leaving unspecific 
what else may be.  In later C++ standards (for example C++14), 
[atomics.lockfree] defines additional types that are atomic.


1 - I use n843 for C99, which is slightly different from the standard, but in 
this case I suspect it is the same.

Reply via email to