This is the mail archive of the gcc-patches@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]
Other format: [Raw text]

Re: [PATCH] Fix PR middle-end/26306


> You're reading too much into the comment.  It's not just GCC history; 
> it's sensible semantics, at least for C and C++.  A volatile lvalue, all 
> by itself, e.g.:
> indicates a memory reference.  The C/C++ standards don't specify the 
> behavior here; they explicitly leave it unspecified.  But, we can 
> specify it, and specifying it to copy "i" to a temporary is a reasonable 
> thing to do.
> 
> However, if S has 
> a copy constructor, then defining the semantics in terms of a copy 
> doesn't make sense, since the C++ standard specifies the times a copy 
> constructor can be called, and this is not one of those times.

My view is that this particular aspect of "volatile" (the load when no value
is needed) really dates back the "C as assembler language" days and meant to
access the particular memory-mapped device register, by copying it into a
register if that's the only way to do it, but some other access (e.g., the
PDP-11 TST instruction) if not.

When you're talking about an aggegate type, you can easily get caught up in
higher-level semantics.  As you say, invoking a copy constructor on such a
thing would be surprising.  Similarly, though you could allocate temporary
memory for a copy and copy it there, all you really need do is access each
byte of the object.

But how?  Access each byte, each short, each word, etc?  In the memory-mapped
device case, the only one that's relevant, it matters which way you access
it.  And it's not clear.  Does it mean you access each field using the mode
for the field (what about bitfields, then?) or does it mean you access every
byte in bulk using some mode that we guess using some heuristic.

Nobody writes code that does this sort of stuff anymore: volatile is
typically used for very different purposes now (shared memory).  So, in my
opinion, all we care about is legacy code and for that, the only important
thing is to generate EXACTLY the same things we used to: trying to define
some new semantic for a case that nobody will use in modern code seems
dubious to me.


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