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.