On 24/09/2011 18:25, John Regehr wrote:
it. And while I think the compiler should be allowed to generate the
optimised code of 4.6 (i.e., the change is not a bug IMHO), I fully
understand the idea of generating the older, slower, but definitely
correct code of 4.5.
My understanding is that the standard mandates the old behavior, so 4.6
is in error.
I am still trying to imagine a real-world use-case for declaring an
object "static const" and later accessing it as "volatile".
Yeah, it would seem far clearer to declare it as static const volatile
in the first place.
I still can't think why one would ever want such a thing.
There is a big difference between defining an object as "const", and
merely declaring it as const or accessing it as const. When you access
it as const, you are saying "/I/ won't change the object with this
access". When you declare an object as const (such as an extern
object), you are saying "/I/ won't change this object". When you
/define/ an object as const, as you do with a "static const", you are
saying "this object is constant. It will never change value - you (the
toolchain) can safely place it in read-only memory that cannot ever
change value".
And then you make it volatile, telling the compiler "this object might
change unexpectedly, or use values written to it unexpectedly".
If someone could explain to me how this could have real-world usage, I
think it would be easier for me (and others) to be sure of what it
really means.
I've done a bunch of automated testing of GCC's implementation of
volatile. None of that testing would have exposed this bug because we
only count acceses to objects declared as volatile.
I've come to the conclusion that "volatile" is a language design error.
It complicates the compiler implementation and has confusing,
underspecified semantics. If you want to force a load or store, an
explicit function call is a clearer way to do it.
I agree on that, as I think do many - "volatile" is not defined clearly
enough. It is also not flexible enough for optimal code generation in
many cases when it is used regularly, such as for embedded programming.
There it is not uncommon to want something that has volatile write
accesses, but does not need volatile read accesses. It gets seriously
messy when you combine "volatile" with bitfields - the standards are
(AFAIK) unclear, and implementations of volatile bitfields vary wildly.
And since "volatile" does not have any interaction with things like
cpu instruction re-ordering, speculative accesses, write buffering and
combining, caches, etc., or with any operating system specific
interactions, it often doesn't do what the user thinks it will do.
However, it is currently the only tool we have in C.