How should C++ code access memory that is shared with another application, e.g. through a memmap
d file? The options seem to be:
- Regular raw accesses, e.g.
int* p = ...address of shared memory...; *p = 5; *p
. This seems unsafe because the compiler is allowed to assume that the contents ofp
are stable which is not the true. - One way to think of these operations is that they are input/output to another process, so (at least in old versions of C++) the way that this should be achieved seems to be with
volatile
. - Since modern-C++ contains builtin atomic operations, another option is to use atomics. In practice, compilers don't seem to do much optimization around these operations, but it isn't clear that it is forbidden by the standard.
From experiments, it seems that both 2 and 3 work in practice (2 not properly handling the intricacies of weak memory), but is either standards compliant? Do I need to use a combination, i.e. accesses to atomic<volatile int>
?
atomic
s don't needvolatile
. Atomics may have internal structure and could break in interesting ways if used with shared memory (the "does not require" in the linked doc is a bit worrying). I would stick to C-style data types and volatile for now. – Threadbareatomic<int>
,atomic<long>
, etc. I need to make the assumption that these are all lock free. I could also do the atomic compiler builtins directly, but the standard doesn't say anything about those. – Dragoman