我对C和C++中
此外,我认为使用像
在我看来,这是支持使用
然而,我使用指向易失对象的指针和
在访问共享内存方面,有哪些关于
volatile
的语义理解是,它将内存访问转换为(observable)副作用。每当读取或写入内存映射文件(或共享内存)时,我希望指针被标记为volatile限定符,以表明这实际上是I/O操作。(John Regehr在volatile
的语义方面写了一篇非常好的文章)。此外,我认为使用像
memcpy()
这样的函数来访问共享内存是不正确的,因为函数签名表明volatile限定符被强制转换掉了,内存访问没有被视为I/O。在我看来,这是支持使用
std::copy()
的论据,其中volatile限定符不会被强制转换掉,内存访问会被正确地视为I/O。然而,我使用指向易失对象的指针和
std::copy()
访问内存映射文件的经验表明,它比仅使用 memcpy()
慢几个数量级。我倾向于得出结论,也许clang和GCC在处理volatile
时过于保守。是否是这种情况?在访问共享内存方面,有哪些关于
volatile
的指导方针,如果我想遵循标准并使其支持我所依赖的语义?
标准中相关引用 [intro.execution] §14:
读取由volatile glvalue指定的对象、修改对象、调用库I/O函数或调用执行这些操作的函数都是副作用,即更改执行环境状态的变化。一般情况下,表达式(或子表达式)的求值包括值计算(包括为glvalue评估确定对象的标识和为prvalue评估获取先前分配给对象的值)和启动副作用。当库I/O函数的调用返回或评估通过volatile glvalue的访问时,副作用被视为完成,即使一些由调用隐含的外部操作(例如I/O本身)或由volatile访问可能尚未完成。