On Aug 21, 2014, at 4:22 AM, Richard Biener <[email protected]> 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.