当前位置:  开发笔记 > 编程语言 > 正文

如何在不引起UB的情况下将字节序列重新解释为POD结构?

如何解决《如何在不引起UB的情况下将字节序列重新解释为POD结构?》经验,为你挑选了0个好方法。

假设我们将一些数据作为一个字节序列获得,并希望将该序列重新解释为一个结构(有一些保证数据确实是正确的格式).例如:

#include 
#include 
#include 
#include 
#include 

struct Data
{
    std::int32_t someDword[629835];
    std::uint16_t someWord[9845];
    std::int8_t someSignedByte;
};

Data* magic_reinterpret(void* raw)
{
    return reinterpret_cast(raw); // BAD! Breaks strict aliasing rules!
}

std::vector getDataBytes()
{
    std::ifstream file("file.bin",std::ios_base::binary);
    if(!file) std::abort();
    std::vector rawData(sizeof(Data));
    file.read(rawData.data(),sizeof(Data));
    if(!file) std::abort();
    return rawData;
}

int main()
{
    auto rawData=getDataBytes();
    Data* data=magic_reinterpret(rawData.data());
    std::cout << "someWord[346]=" << data->someWord[346] << "\n";
    data->someDword[390875]=23235;
    std::cout << "someDword=" << data->someDword << "\n";
}

现在magic_reinterpret这里实际上是坏的,因为它打破了严格的别名规则,从而导致UB.

它应该如何实现不会导致UB而不执行任何数据副本memcpy


编辑:getDataBytes()上面的函数实际上被认为是一些不可改变的功能.一个真实的例子是ptrace(2),在Linux上,何时request==PTRACE_GETREGSETaddr==NT_PRSTATUS(根据x86-64)写入两种不同大小的结构中的一种,具体取决于跟踪位数,并返回大小.这里ptrace调用代码无法预测它实际执行调用之前将获得的结构类型.那怎么能安全地重新解释它得到的结果作为正确的指针类型?

推荐阅读
wurtjq
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有