首页 > 解决方案 > 使用 POD-struct 的 reinterpret_cast 理解代码示例

问题描述

我找到了一些代码,并想确保我正确理解了这一点。用例是由值数组表示的打包图像。在本例中,三个值代表一个像素。

我找到的代码是这样的:

struct Pixel{ 
  int[3] data
  int x(){return data[0];}
  int y(){return data[1];}
  int z(){return data[2];}
};

void main(){

  std::vector<int> img(300);
  Pixel* access = reinterpret_cast<Pixel*>(img.data()+3*5);
  foo(access->x());
}

正如我从阅读POD 和标准布局中了解到的那样,我认为代码示例是有效的,因为我们只使用了 Pixel 的第一个成员?然后将 Pixel 替换为

struct Pixel2{
  int red;
  int green;
  int blue;
};

会导致未定义的行为吗?

编辑:我使用 cuda 并找到了另一个示例:将无符号字符指针(一个数组)转换为 uchar3 指针。uchar3 类型定义等于第二个像素定义。这是否意味着第二个也有效?还是这仅适用于 nvcc 编译的代码?如果第二个像素定义是有效的,那为什么?

编辑:为了进一步强调代码试图做什么,我重命名了上面的一些字段:我有一个原始数据数组。在我的情况下,这是一个打包的图像。我想要一种访问像素及其值的好方法。所以我可以做这样的事情:

void bar(int* data,size_t size)
{
   Pixel2* img = reinterpret_cast<Pixel*>(data);
   std::cout << "Pixel 13 has blue value: " << img[13].blue;
}

我已经看到在 cuda 中使用它的代码并且它有效,但我想知道它是否总是好的,因为我读到的关于 POD 的内容似乎没有涵盖它。我只是错过了关于 POD 的一些东西,还是这可能会失败?

编辑:是否有区别:

  foo(access->x());
  foo(access->data[0]);

我认为第二个应该是合法的,因为对于 POD 类型,第一个成员变量与对象具有相同的地址?

编辑:我从答案中得到的是:在我提到的所有情况下都是 UB。那么要走的路将是一个随机访问迭代器,它给我我想要的访问权限。

标签: c++c++14standard-layout

解决方案


在不存在的对象上调用非静态成员函数和对不存在的对象上的非静态数据成员执行类成员访问都是未定义的行为。

您的代码中没有任何内容创建PixelPixel2对象。


推荐阅读