Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.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++_Arrays_Struct_Language Lawyer_Static Cast - Fatal编程技术网

C++ 将双数组强制转换为双数组结构

C++ 将双数组强制转换为双数组结构,c++,arrays,struct,language-lawyer,static-cast,C++,Arrays,Struct,Language Lawyer,Static Cast,将双精度数组强制转换为由双精度数组组成的结构可以吗 struct A { double x; double y; double z; }; int main (int argc , char ** argv) { double arr[3] = {1.0,2.0,3.0}; A* a = static_cast<A*>(static_cast<void*>(arr)); std::cout << a->x <&

将双精度数组强制转换为由双精度数组组成的结构可以吗

struct A
{
   double x;
   double y;
   double z;
};

int main (int argc , char ** argv)
{
   double arr[3] = {1.0,2.0,3.0};
   A* a = static_cast<A*>(static_cast<void*>(arr));
   std::cout << a->x << " " << a->y << " " << a->z << "\n";
}
然后它就保证工作了。对的我知道很多人不会觉得这很美,但使用结构和不必复制输入数组数据有好处。我可以在该结构中定义成员函数来计算标量和向量积、距离等,这将使我的代码比使用数组更容易理解

怎么样

int main (int, char **)
{
   double arr[6] = {1.0,2.0,3.0,4.0,5.0,6.0};
   A* a = reinterpret_cast<A*>(arr);
   std::cout << a[0].x() << " " << a[0].y() << " " << a[0].z() << "\n";
   std::cout << a[1].x() << " " << a[1].y() << " " << a[1].z() << "\n";
}
int main(int,char**)
{
双arr[6]={1.0,2.0,3.0,4.0,5.0,6.0};
A*A=重新解释铸件(arr);

std::cout不,不能保证

唯一禁止任何编译器在
x
y
之间,或
y
z
之间插入填充的东西是常识。任何语言标准中都没有规则不允许这样做


即使没有填充,即使
A
的表示形式与
double[3]
的表示形式完全相同,它仍然无效。该语言不允许您假装一种类型是另一种类型。您甚至不允许将
结构A{int i;};
的实例视为
结构B{int i;};

据我所知,答案是:是的


唯一可能让您感到不舒服的是一个#pragma指令,它为结构设置了一些非常不寻常的对齐设置。例如,如果一个double在您的计算机上占用8个字节,而#pragma指令告诉您在16个字节的边界上对齐每个成员,这可能会导致问题。除此之外,您很好。

不,即使它应该适用于我所知道的所有通用体系结构的编译器,因为C语言规范规定:

6.2.6类型的表示 6.2.6.1概述1除本款所述外,所有类型的表示均未指定。且未说明结构中的默认填充

当然,常见的体系结构最多使用64位,这是那些体系结构上的一个双精度大小,因此应该没有填充,您的转换应该可以工作


但是要当心:您明确地调用了未定义的行为,下一代编译器在编译这样的强制转换时可以做任何事情。

我不同意这里的共识。一个包含三个双精度的结构与一个包含三个双精度的数组完全相同。除非您特别以不同的方式打包该结构,并且是在一个奇怪的处理器上,该处理器的双倍字节数为奇数


它没有内置到语言中,但我会觉得这样做很安全。就风格而言,我不会这样做,因为它只是让人困惑。

该标准对对象的内存布局几乎没有保证

对于类/结构:

9.2./15:分配具有相同访问控制的类的非静态数据成员,以便以后的成员具有更高的地址 在类对象中。非静态数据的分配顺序 未指定具有不同访问控制的成员。实现 对齐要求可能会导致两个相邻的成员不能紧跟在一起进行分配;对 用于管理虚拟函数和虚拟基类的空间

对于数组,元素是连续的。没有关于对齐的说明,因此它可能使用或可能不使用与struct中相同的对齐规则:

8.3.4:数组类型的对象包含一组连续分配的非空的T类型N个子对象

在您的具体示例中,您唯一可以确定的是,如果使用重新解释类型,则
a.x
对应于
arr[0]

9.2.21:指向标准布局结构对象的指针(使用重新解释转换进行适当转换)指向其初始成员(…) 反之亦然。[
>


msvc的复杂实现使用数组解决方案,llvm libc++使用前一种形式


我想,只要检查一下您的libc++的std::complex的实现,并使用相同的解决方案即可。

任何人都可以编写编译器,所以这是一个棘手的问题。为什么不指定您将要使用的编译器呢?我想所有主要的编译器都是一样处理这个问题的,而且它确实可以工作。很可能不是(如果您不想在此处仅使用double),因为您违反了严格的别名规则。在这种情况下,
A
是。理论上可以使用填充(double
不太可能,但长double很可能)但在任何情况下,结构和数组都将具有相同的填充。这都是假设没有
#pragma
来覆盖对齐规则。此外
A
B
彼此.layout兼容(尽管与数组不兼容)
int main (int, char **)
{
   double arr[6] = {1.0,2.0,3.0,4.0,5.0,6.0};
   A* a = reinterpret_cast<A*>(arr);
   std::cout << a[0].x() << " " << a[0].y() << " " << a[0].z() << "\n";
   std::cout << a[1].x() << " " << a[1].y() << " " << a[1].z() << "\n";
}