I found some code and want to make sure that I understand this correctly. The usecase is an packed image that is represented by an array of values. In this example three values represent one pixel.
The code I found goes something like this:
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());
}
As I understand from reading POD and standard layout, I think the code example is valid, because we only use the first member of Pixel? Then replacing Pixel with
struct Pixel2{
int red;
int green;
int blue;
};
will result in undefined behaviour?
Edit: I work with cuda and found another example: casting and unsigned char pointer (an array) to an uchar3 pointer. The uchar3 type definition is equal to the second pixel definiton. Does this mean the second is also valid? Or does this only works for code compiled by nvcc? If the second Pixel definition is valid, then why?
Edit: To further emphasis what the code is trying to do I renamed some fields above: I have an array of raw data. In my case that is an packed image. I want to have an nice way to access the pixel and their values. So I can do something like this:
void bar(int* data,size_t size)
{
Pixel2* img = reinterpret_cast<Pixel*>(data);
std::cout << "Pixel 13 has blue value: " << img[13].blue;
}
I have seen code using this in cuda and it worked, but I want to know if it is allways okay, since it seems not covered by what I read about POD. Do I just missed something about POD or is this something that can fail?
Edit: is There a difference between:
foo(access->x());
foo(access->data[0]);
I thought second should be legal since for POD-types the first member variable has the same address as the object?
Edit: What I take from the answers is: that is UB in all cases I mentioned. The way to go would then be an random-access-iterator that gives me the access I would like.
Calling a non-static member function on a nonexistent object and performing a class member access for a non-static data member on a nonexistent object are both undefined behavior.
Nothing in your code creates a
Pixel
orPixel2
object.