C++ C++;使用新位置构造的易失性对象

C++ C++;使用新位置构造的易失性对象,c++,concurrency,x86,C++,Concurrency,X86,我正在使用placement new构建一个位于内存中某处的对象(例如内存映射IO): 在我的消费者代码中,我在mui上有几个分支。我认为必须将其标记为volatile,否则编译器可能会将其存储在寄存器中,而分支将检查该寄存器而不是存储在内存中的值,这对吗 目前,我没有将其标记为volatile,而是使用编译器围栏,例如asm volatile(“::“I,r,m”(mu I:“memory”),这足够了吗 我在这里只对x86感兴趣,而对任何其他体系结构都不感兴趣。另外,有一个进程写入这个内存区

我正在使用placement new构建一个位于内存中某处的对象(例如内存映射IO):

在我的消费者代码中,我在
mui
上有几个分支。我认为必须将其标记为
volatile
,否则编译器可能会将其存储在寄存器中,而分支将检查该寄存器而不是存储在内存中的值,这对吗

目前,我没有将其标记为
volatile
,而是使用编译器围栏,例如
asm volatile(“::“I,r,m”(mu I:“memory”),这足够了吗

我在这里只对x86感兴趣,而对任何其他体系结构都不感兴趣。另外,有一个进程写入这个内存区域,另一个进程消耗内存,但我的问题不是并发性问题,而是编译器优化过程中可能出现的错误


编辑:固定位置新语法,将类更改为struct

我认为必须将其标记为volatile是否正确?否,它应该是
std::atomic
。C++11已经存在了将近十年,使用
volatile
滚动你自己的
内存\u顺序
是愚蠢的。参见@PeterCordes问题还提到变量的位置是内存映射IO,我认为
volatile
是一个有效的用例,不是吗?@walnut:我刚刚注意到它是实际的MMIO:P,但它也是由多个进程读/写的,所以这是
volatile std::atomic m_I(实际上,它将编译成与普通
std::atomic m_i
相同的机器代码(因为编译器不会优化原子),如果使用
mo_i
,也将编译成与普通
volatile m_i
相同的机器代码。(或由于编译器的特殊性而产生的细微差异,如gcc不使用
volatile
对象作为内存源操作数。)顺便说一句,
asm
如果你仔细了解asm内存模型,内存障碍可以用于并发,但不适用于MMIO。这不会阻止编译器在源代码读取内存一次时读取内存两次,如果读取有副作用则不可以。@walnut谢谢,我写得有点太快了,修复了语法。我正确吗ct认为它必须被标记为volatile-不,它应该是
std::atomic
。C++11已经存在了将近十年,使用
volatile
滚动你自己的
内存顺序
是愚蠢的。请看@PeterCordes这个问题还提到变量的位置是内存映射IO,我认为
>volatile
是一个有效的用例,不是吗?@walnut:我刚刚注意到它是实际的MMIO:P,但它也是由多个进程读/写的,因此这是
volatile std::atomic m_I;
的一个用例(实际上它将编译成与普通
std::atomic m_I
相同的机器代码)(因为编译器不会优化原子),如果您使用
mou-relaxed
也可以将相同的机器代码转换为普通
volatile m\u i
(或者由于编译器的特殊性而产生的微小差异,例如gcc不使用
volatile
对象作为内存源操作数。)顺便说一句,
asm
如果你仔细了解asm内存模型,内存障碍可以用于并发,但对于MMIO则不行。这不会阻止编译器在源代码读取内存一次时读取内存两次,如果读取有副作用则不行。@walnut谢谢,我写得有点太快了,修复了语法。
struct alignas(16) A
{
    std::uint32_t m_i;
};

...

A* pA = new (memArena) A();