Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.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++_Struct_Language Lawyer_Strict Aliasing - Fatal编程技术网

C++ “那”是怎么回事;包含上述类型之一的聚合或联合类型;严格的别名规则?

C++ “那”是怎么回事;包含上述类型之一的聚合或联合类型;严格的别名规则?,c++,struct,language-lawyer,strict-aliasing,C++,Struct,Language Lawyer,Strict Aliasing,以前,在basic.lval中,有一个要点: 在其元素或非静态数据成员(递归地包括子集合或包含的联合的元素或非静态数据成员)中包含上述类型之一的聚合或联合类型 在水流中,它消失了 WG21网站上有一些背景信息: < > 7.2.1[Basic LVA]段10的混叠规则是从C中加入C++的。然而,许多点或者不适用,或者被其他点包含。例如,在C++中,对于结构分配需要提供聚合和联合类型,C++中的构造函数和赋值操作符是C++中的,不是通过访问完整对象来实现的。 谁能给我解释一下,这是什么意思?这个严

以前,在basic.lval中,有一个要点:

在其元素或非静态数据成员(递归地包括子集合或包含的联合的元素或非静态数据成员)中包含上述类型之一的聚合或联合类型

在水流中,它消失了

WG21网站上有一些背景信息:

< > 7.2.1[Basic LVA]段10的混叠规则是从C中加入C++的。然而,许多点或者不适用,或者被其他点包含。例如,在C++中,对于结构分配需要提供聚合和联合类型,C++中的构造函数和赋值操作符是C++中的,不是通过访问完整对象来实现的。 谁能给我解释一下,这是什么意思?这个严格的别名规则与C中的结构赋值有什么关系

关于这条规则:

这些项目符号描述了C语言中不能出现的情况++

我不明白,为什么这是真的。比如说,

struct Foo {
    float x;
};

float y;
float z = reinterpret_cast<Foo*>(&y)->x;
structfoo{
浮动x;
};
浮动y;
浮动z=重新解释铸件(&y)->x;
最后一行似乎和要点描述的一样。它通过聚合访问
y
(a
float
),该聚合包括
float
(成员
x


有人能解释一下吗?

您用来访问
y
的存储值的左值不是
*reinterpret\u cast(&y)
,类型为
Foo
,而是
reinterpret\u cast(&y)->x
,类型为
float
。使用
float
类型的左值访问
float
是可以的。在C++中,不能访问“联合或结构”的值(作为整个),只能访问单个成员。您引用的理由指出了C和C++之间的区别:

  struct X { int a, b; };
  struct X v1 = {1, 2}, v2;
  v2 = v1;
在C中,标准规定赋值加载
v1
(作为一个整体)的值以将其赋值给
v2
。这里,使用类型为
struct X
(不是
int
)的左值访问对象
v1.a
v2.b
(两者都具有类型
int
)的值

在C++中,标准称赋值调用编译器生成赋值操作符,相当于

struct X {
   ...
   struct X& operator=(const struct X&other)
   {
       a = other.a;
       b = other.b;
   }
};

在这种情况下,调用赋值运算符不会访问任何值,因为RHS是通过引用传递的。执行赋值操作符分别访问两个
int
字段(这很好,即使没有聚合规则),因此,这同样不是通过类型为
struct X

的左值来访问值,如果从
malloc
接收的存储是使用一个pod写入的,而使用另一个具有相同布局的pod读取的,那么规则会怎么说呢?我同意这个答案,但我认为问题中有一个不成文的假设是
A.B
“访问”
A
(因此
P->B
“访问”
*P
)。我看不到标准中有任何明确说明不是这样的,但事实上,
A.B
本身并不意味着任何支持它的东西的修改或左值对右值。@supercat这个规则仍然可以接受。如果这两种类型是布局兼容的,则各个成员是布局兼容的。如果它们是布局兼容的,那么通过指向不同POD类型的指针从一个POD类型访问成员,这在“别名子句”中前面的一个项目符号中有所涉及。@MichaelKarcher:据我所知,gcc和clang都不支持这种用法。要使C规则发挥作用,需要认识到通过指针进行的访问(显然是从左值派生的)应该被视为对该左值的访问,但gcc也不支持这种用法?我们不能说在
float z=reinterpret\u cast(&y)->x
我们通过类型为
float
的左值访问
y
,因此这也很好?第一个要点无论如何(在两种语言中)都没有多大意义,所以我很高兴看到它消失了@M.M.你能解释一下“两种语言中的任何一种”的说法吗?@language律师用C或C++@M.M.我的意思是为什么它在C@LanguageLawyer假设你有
结构{inta;float b;}
float*c=malloc(100)
和int与float大小相同,没有填充;然后
c[0]=c[1]=0;S=*(S*)c不是别名冲突,因为
float
c[0]
是由一个聚合类型访问的,该聚合类型的成员是
float
(不要介意成员的偏移量与被访问的内存不对应)