我可以安全地将浮点数的结构转换为浮点数组吗C++?
Can I safely convert struct of floats into float array in C++?
例如我有这个结构
struct A {
float x;
float y;
float z;
};
我可以这样做吗?A a; float* array = (float*)&a;
并使用 as 浮点数组?
在实际意义上,是的,你可以这样做,它将适用于所有最常用的架构和编译器。
请参阅维基百科上的"x86 上 C 结构的典型对齐方式"部分。
更多详情:
-
浮点数为 4 个字节,不会插入填充(在几乎所有情况下(。
-
此外,大多数编译器都可以选择指定结构的打包,并且可以强制不插入填充(即来自Visual Studio的 #pragma 包(
-
数组保证在内存中是连续的。
你能保证它能在世界上所有的CPU上用所有的编译器工作吗?哈哈。但我绝对希望看到一个失败的平台:)
编辑:如果有填充字节,添加static_assert(sizeof(A) == 3*sizeof(float))
将使此代码无法编译。因此,您将确保它在编译时可以正常工作。
不,将struct
类型转换为数组将不起作用。允许编译器在成员之间添加填充。
数组在成员之间没有填充。
注意:没有什么可以阻止您进行强制转换,但是,在转换后使用值会导致未定义的行为。
这是一个严格的混叠冲突,简单明了。在该指针的任何访问中,指向除第一个元素之外的任何元素都是未定义的行为。在更复杂的情况下,无论您访问哪个元素,它都只是普通的未定义行为。
如果需要数组,请使用数组。std::array
还有一个重载 for forstd::get
,所以你可以用它来命名每个单独的数组成员:
using A = std::array<float, 3>;
enum AElement { X, Y, Z };
int main() {
A a;
get<X>(a) = 3.0f; // sets X;
float* array = a.data(); // perfectly well defined
}
对于 g++,你可以对结构使用属性,如下所示:
struct A {
float x;
float y;
float z;
}__attribute__((__packed__));
它禁用结构对齐。
你可以这样做,直到编译器开始优化,然后出现问题。
使用指向第一个元素的指针访问结构的第一个元素以外的任何元素都是未定义的行为。"未定义的行为"意味着任何事情都可能发生。编译器可以假定没有未定义的行为。
编译器可以从中推断出许多后果:如果编译器知道您的 float* 指向结构的第一个元素,那么它可以推断出该数组的每个索引都等于 0(因为其他任何内容都是未定义的行为(。如果编译器不知道这一点,那么它可以推断数组指针不能指向结构,并且更改数组元素不能更改结构元素,反之亦然。
你能看到这将如何出错吗?
- Mongodb c++驱动程序:如何查询元素的数组
- 将数组的地址分配给变量并删除
- 从C++本机插件更新Vector3数组
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 数组索引的值没有增加
- 将对象数组的引用传递给函数
- 为char数组调整zlib-zpipe
- 2D数组来自文本输入,中间有空格
- std::向量与传递值的动态数组
- 在c++中用vector填充一个简单的动态数组
- 使用strcpy将char数组的元素复制到另一个数组
- 使用指针从C++中的数组中获取最大值
- C++使用整数的压缩数组初始化对象
- 告诉一个 const char 数组,除了编译时 C 样式的字符串外,它不以 '