いくつかのコードを見つけたので、これを正しく理解していることを確認したいと思います。ユースケースは、値の配列で表されるパックされたイメージです。この例では、3 つの値が 1 つのピクセルを表しています。
私が見つけたコードは次のようになります。
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 と standard layoutを読んでわかるように、Pixel の最初のメンバーしか使用していないため、コード例は有効だと思いますか? 次に、Pixelを次のように置き換えます
struct Pixel2{
int red;
int green;
int blue;
};
未定義の動作になりますか?
編集:私はcudaを使用して、別の例を見つけました:uchar3ポインターへのキャストおよびunsigned charポインター(配列)。uchar3 型の定義は、2 番目のピクセルの定義と同じです。これは、2番目も有効であることを意味しますか?それとも、これは nvcc によってコンパイルされたコードに対してのみ機能しますか? 2 番目の Pixel 定義が有効である場合、その理由は何ですか?
編集:コードが何をしようとしているのかをさらに強調するために、上記のいくつかのフィールドの名前を変更しました:生データの配列があります。私の場合、それはパックされたイメージです。ピクセルとその値にアクセスするための良い方法が必要です。だから私はこのようなことができます:
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 型の場合、最初のメンバー変数がオブジェクトと同じアドレスを持っているため、2 番目は合法であるべきだと思いましたか?
編集:回答から得たものは、私が言及したすべてのケースでUBです。進むべき道は、私が望むアクセスを私に与えるランダムアクセスイテレータです。