Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C/C++;内存模型允许原子在相同字节中具有不同的粒度?_C++_C_Language Lawyer - Fatal编程技术网

C++ C/C++;内存模型允许原子在相同字节中具有不同的粒度?

C++ C/C++;内存模型允许原子在相同字节中具有不同的粒度?,c++,c,language-lawyer,C++,C,Language Lawyer,假设我有以下类型: struct{ int32高; int32低; }; 是否定义了对所有x、&x->high和&x->low(假设U*x)执行原子访问(例如使用atomic\U load、atomic\U fetch\U add)的行为 我的理解是,C/C++内存模型是使用单个位置的历史记录定义的(以适应较弱的内存体系结构)。如果访问可以跨位置,这是否意味着跨位置同步?如果是这种情况,那么我假设这意味着历史记录基本上是每个字节的,访问int就像在底层4(或8)字节之间同步一样 编辑:修改示例

假设我有以下类型:

struct{
int32高;
int32低;
};
是否定义了对所有
x
&x->high
&x->low
(假设
U*x
)执行原子访问(例如使用
atomic\U load
atomic\U fetch\U add
)的行为

我的理解是,C/C++内存模型是使用单个位置的历史记录定义的(以适应较弱的内存体系结构)。如果访问可以跨位置,这是否意味着跨位置同步?如果是这种情况,那么我假设这意味着历史记录基本上是每个字节的,访问
int
就像在底层4(或8)字节之间同步一样

编辑:修改示例以避免联合,因为问题的主要部分是关于并发模型的


编辑:修改为使用标准原子,从
stdatomic.h
加载非活动的联盟成员会产生一个不确定的值,无论是否使用
\uuu原子加载
进行加载。

对于C11/C18(我不能谈论C++)标准
原子加载
的函数仅定义为采用
\u原子的
限定参数。因此,要对结构T的字段执行
atomic_xxx()
操作,您需要:

struct T {
  _Atomic int32 high;
  _Atomic int32 low;
} ;

struct T foo, bar ;
然后你就可以做(例如)
atomic\u fetch\u add(&foo->high,42)
。但是
bar=atomic\u load(&foo)
将是未定义的

相反,您可以:

struct T {
  int32 high;
  int32 low;
} ;

_Atomic struct T foo ;
        struct T bar ;
现在定义了
bar=atomic_load(&foo)
。但是对
foo
中任何单个字段的访问都是未定义的——不管它是否是
\u原子的

按照标准,
\u原子xxxx
对象应被视为与“普通”
xxxx
对象完全不同——它们可能具有不同的大小、表示和对齐方式。因此,将一个
xxxx
转换为一个
\u原子xxxx
并不比将一个
struct
转换为另一个不同的
struct
更明智


但是对于gcc和
\uuuuu atomic\uxxx()
内置,您可以执行处理器支持的任何操作。事实上,对于gcc(否则)标准
atomic_xxx()
将接受非
\u atomic
限定类型的参数,并映射到内置类型。另一方面,clang将非
\u原子的
限定类型传递给标准函数视为错误。我想澄清一下,这是gcc的

中的一个bug,你不是在问类型双关吗?因为C++中不允许这样做。不确定语言问题是否应该询问非标准函数,如<代码>、μ原子、xxx < /代码>。这些是我知道的唯一的原子操作的原语。原子操作是否有标准函数?
原子操作是否有标准函数?
和。(双代码< >代码>建议)是GNU扩展。C和C++内存模型不允许原子函数在某种意义上。它们有原子类型,您可以对其执行原子操作。