gpt4 book ai didi

c++ - 通过浮点指针操作字节 vector

转载 作者:行者123 更新时间:2023-12-01 20:06:31 26 4
gpt4 key购买 nike

是否可以操纵 std::vector<unsigned char>通过它的数据指针,就好像它是 float 的容器一样?

这是一个根据需要编译和(看起来?)运行的示例(GCC 4.8,C++11):

#include <iostream>
#include <vector>

int main()
{
std::vector<unsigned char> bytes(2 * sizeof(float));
auto ptr = reinterpret_cast<float *>(bytes.data());
ptr[0] = 1.1;
ptr[1] = 1.2;
std::cout << ptr[0] << ", " << ptr[1] << std::endl;
return 0;
}

此代码片段成功从字节缓冲区写入/读取数据,就好像它是 float 的数组一样。 。来自 reading about reinterpret_cast恐怕这可能是未定义的行为。我对理解类型别名细节的信心太小,无法确定。

代码片段是否如上所述未定义行为?如果是这样,是否有另一种方法来实现这种字节操作?

最佳答案

法律答复

不,这是不允许的。

C++ 不仅仅是“一堆字节”——编译器(更抽象地说,是语言)被告知你有一个 unsigned char 的容器。 s,不是 float 的容器s。否float它们确实存在,但你不能假装它们确实存在。

您要查找的规则(称为“严格别名”)可以在 [basic.lval]/8 下找到。 .

反之亦然,因为允许(通过同一段落中的特殊规则)通过 unsigned char* 检查任何类型的字节。 。但就您而言,“获取” float 的最快安全且正确的方法从生命开始为 unsigned char 的东西是std::memcpystd::copy这些字节转换为实际的 float存在:

std::vector<unsigned char> bytes(2 * sizeof(float));
float f1, f2;

// Extracting values
std::memcpy(
reinterpret_cast<unsigned char*>(&f1),
bytes.data(),
sizeof(float)
);

std::memcpy(
reinterpret_cast<unsigned char*>(&f2),
bytes.data() + sizeof(float),
sizeof(float)
);

// Putting them back
f1 = 1.1;
f2 = 1.2;

std::memcpy(
bytes.data(),
reinterpret_cast<unsigned char*>(&f1),
sizeof(float)
);

std::memcpy(
bytes.data() + sizeof(float),
reinterpret_cast<unsigned char*>(&f2),
sizeof(float)
);

只要这些字节形成 float 的有效表示就可以了。在您的系统上。诚然,它看起来有点笨重,但快速的包装函数可以让它很快完成工作。

一个常见的替代方案,假设您只关心 float s 并且不需要可调整大小的缓冲区,就是产生一些 std::aligned_storage 然后在生成的缓冲区中进行一堆placement new。从 C++17 开始,您也可以使用 std::launder ,尽管在这种情况下调整 vector 大小(读取:重新分配其缓冲区)也是不可取的。

此外,这些方法非常复杂,并且会产生复杂的代码,并非所有读者都能理解。如果您可以清洗您的数据,使其"is"float 的序列s,你不妨把自己变成一个好人std::vector<float>首先。根据上述内容,允许获取和使用 unsigned char*如果您愿意的话,可以到该缓冲区。

应该指出的是,有很多代码使用了您原来的方法(特别是在具有准系统 C 传统的旧项目中)。在许多实现中,它似乎可以工作。但它是有效和/或安全的,这是一个常见的误解,如果您依赖它,您很容易接受“重新排序”(或其他优化)指令。

<小时/>

对冲投注答案

无论如何,如果您禁用严格别名(GCC 允许将其作为扩展,而 LLVM 甚至不实现它),那么您可能可以摆脱原始代码。 Just be careful .

关于c++ - 通过浮点指针操作字节 vector ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61911765/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com