C++ Logo


Advanced search

Re: pointer to volatile, but no volatile object

From: David Brown <david_at_[hidden]>
Date: Tue, 6 Jun 2023 11:40:52 +0200
On 06/06/2023 07:02, Federico Kircheis via Std-Discussion wrote:
> On Mon, Jun 05, 2023 at 03:41:45PM -0700, Thiago Macieira via
> Std-Discussion wrote:
>> On Monday, 5 June 2023 12:42:12 PDT Federico Kircheis via Std-Discussion
>> wrote:
>>> For what is worth, even a static_cast seems to hinder optimizations
>>> void foo(){
>>> int a = -1;
>>> *static_cast<volatile int*>(&a) = 42;
>>> }
>> The compilers probably think that "if you are trying to waste CPU
>> cycles here,
>> you must have a reason".
> XD
> The question is if the standard thinks the same too, or if this is
> accepted practice by all compilers.

I'm not sure about the situation for C++, but I know (or have heard) a
little about it for C - and I believe C++ compilers will treat things
the same way.

Originally, the C standards referred only to the action on "volatile
objects" - a vital part of the "observable behaviour" of programs was
"Accesses to volatile objects are evaluated strictly according to the
rules of the abstract machine". The interpretation of using
pointer-to-volatile accesses was up to the compiler. But at some point
between C11 and C18, this was discussed by the committee - and they
found that no one had ever even heard of a compiler that did not treat
access via a pointer-to-volatile as anything other than observable
behaviour (with the implication that has on optimisation). So it was
codified in C18 - we now have "Volatile accesses to objects" as
observable behaviour, not "Accesses to volatile objects". And "volatile
accesses" are "access to an object through the use of an lvalue of
volatile-qualified type".

(C still allows things like "v1 += v2 + v3;" and other poorly defined
volatile accesses that are now disallowed in C++.)

So as far as C is concerned, something like :

 void foo(void) {
  int a = -1;
  *((volatile int *) &a) = 42;

is clearly defined in C18 onwards as making the access observable
behaviour - the compiler must generate code that writes 42 to "a". It
doesn't matter that there is no C-defined way to view that write from
anywhere else in the program.

I think C++ makes the same requirements, and that these /are/ guaranteed
by the standards. And to the best of my knowledge, all compilers will
honour the programmer's request to make such accesses "real" observable
behaviour, whatever the standards say.

After all, volatile accesses to local non-volatile variables can
sometimes be useful in the context of debugging - you can use such
accesses to ensure that a variable is actually updated (at least from
the viewpoint of the current thread) at a particular point in the code,
where you might have placed a breakpoint.

Received on 2023-06-06 09:41:00