代码之家  ›  专栏  ›  技术社区  ›  tmlen

充满不同类型数据的缓冲区,以及严格的别名

  •  10
  • tmlen  · 技术社区  · 8 年前

    the standard 它总是在C++中定义未定义的行为,例如 float* 指向与 int* ,然后从中读/写。

    在我拥有的应用程序中,可以有一个由32位浮点元素覆盖的32位整数元素填充的缓冲区。(它实际上包含一个图像的表示,该图像由GPU内核在多个阶段进行转换,但也应该有一个主机实现执行相同的处理,以进行验证。)

    void* buffer = allocate_buffer(); // properly aligned buffer
    
    static_assert(sizeof(std::int32_t) == sizeof(float), "must have same size");
    const std::int32_t* in = reinterpret_cast<const std::int32_t*>(buffer); 
    float* out = reinterpret_cast<float*>(buffer); 
    for(int i = 0; i < num_items; ++i)
       out[i] = transform(in[i]);
    

    有没有办法使 reinterpret_cast 在C++标准内定义的指针实例,不做整个缓冲区的额外内存副本,或附加的每个元素副本(例如 std::bit_cast )?

    2 回复  |  直到 8 年前
        1
  •  6
  •   user32434999    8 年前

    尽管我一直希望有个好办法,但现在没有了。你必须使用 no-strict-aliasing 您选择的编译器的标志。

    为了 std::bit_cast 你得等到 C++20 . 不使用标准的一致性方法 memcpy

    也看看这个 bit_cast proposal 和 this website .

        2
  •  0
  •   Andrea Corbellini    8 年前

    用工会怎么样?例如:

    union T {
        std::int32_t i;
        float f;
    }
    
    T* buffer = allocate_buffer();
    for(int i = 0; i < num_items; ++i)
        buffer[i].f = transform(buffer[i].i);