首页 > 解决方案 > 将整数类型的数组作为另一个不相关的整数类型的数组访问的安全且符合标准的方法?

问题描述

这是我需要做的。我敢肯定,对于许多 C++ 开发人员来说,这是一项常规且可识别的编码任务:

void processAsUint16(const char* memory, size_t size) {
   auto uint16_ptr = (const uint16_t*)memory;
   for (size_t i = 0, n = size/sizeof(uint16_t); i < n; ++i) {
      std::cout << uint16_ptr[i]; // Some processing of the other unrelated type
   }
}

问题:我正在使用集成了 clang 静态代码分析的 IDE 进行开发,并且我尝试的所有转换方式memcpy(我不想诉诸)要么不鼓励要么强烈不鼓励。例如,reinterpret_castCPP 核心指南简单禁止。不鼓励 C 风格的演员表。static_cast不能在这里使用。

避免类型别名问题和其他类型的未定义行为的正确方法是什么?

标签: c++memorytype-conversionc++17type-safety

解决方案


避免类型别名问题和其他类型的未定义行为的正确方法是什么?

您使用memcpy

void processAsUint16(const char* memory, size_t size) {
    for (size_t i = 0; i < size; i += sizeof(uint16_t)) {
        uint16_t x;
        memcpy(&x, memory + i, sizeof(x));
        // do something with x
    }
}

uint16_t是微不足道的可复制的,所以这很好。

或者,在 C++20 中,使用std::bit_cast(尴尬地必须先通过一个数组):

void processAsUint16(const char* memory, size_t size) {
    for (size_t i = 0; i < size; i += sizeof(uint16_t)) {
        alignas(uint16_t) char buf[sizeof(uint16_t)];
        memcpy(buf, memory + i, sizeof(buf));

        auto x = std::bit_cast<uint16_t>(buf);
        // do something with x
    }
}

实际上,如果您只是 ,编译器只会“做正确的事情” reinterpret_cast,即使它是未定义的行为。也许类似的东西std::bless会给我们一个更直接的、非复制的、这样做的机制,但在那之前......


推荐阅读