Kind of looking for people that know their way around the C++ standard for this and might be able to provide a reference to. Say I have a class like this and I use a pointer as an array, whether this can produce undefined behavior or not...
I know I've seen some libraries do this (Doom3's idLib's Vectors do this) and some opengl implementations when passing pointers to attributes of a vertex ie:
1 2 3 4 5 6 7 8
struct Vertex
{
float x, y, z;
float u, v;
} vertex;
glVertexAttribPointer( ..., &vertex.x );
Your first example doesn't make sense to me. Point::x is not an array of floats, so why would you index into it? I've seen people index into variables to get individual bytes (a bad idea because it doesn't take endianness into account) but I don't know what you're trying to do.
The second example is just passing a pointer to float to a function which seems fine to me.
I think the OP is talking about indexing an {float x, y, z, u, v;} struct as if it was an array of floats, staring with a pointer to x.
If that is the case, it is undefined behavior from the standard point of view because pointer arithmetic is only defined within an array (and a compiler is free to ignore that code, or warn about accessing an array out of bounds, etc)
@cubbi
So it is undefined but for the most part I've never seen it fail. Most math libraries I see define vectors as 3 floating point components and are still used and passed to the GPU. Almost feel as though the standard should define something of the sort.
@LB
Again idk why you would want to double the size of a structure and number of memory accesses, not to mention initialization of those references. Especially considering this is a vertex and the shear number that are going to exist, this is something you don't really want.
It's undefined behaviour to write to one union member and then read from another expecting them to share the same memory, so no. You can only read from the one last written.
Yah unions are undefined as well for this example, if you compiler supports anonymous structures this is also commonly used:
1 2 3 4 5 6 7 8 9 10 11
struct Point
{
union
{
struct
{
float x, y;
};
float v[2];
};
};
@vlad
Again using references for a vector is not ideal, you can be double if not tripling the size of the vector depending on the architecture you are on.
I guess the point being, even though this is all undefined almost every math library I see used with opengl defines a vector with variables instead of an array.
Why do you need to be able to index into the vertex like an array anyway? And why can't you, knowing that there are only two values in the array, just do
1 2 3 4 5 6 7 8 9 10 11
struct Point {
float x, y;
float& operator[](int index)
{
switch (index) {
case 0: return x;
case 1: return y;
default: throw std::runtime_error("Point::operator[] only defined for indices 0 and 1");
}
}
};
It's no worse than any other solution that hardcodes the size of the array, and it doesn't take any extra memory because every Point object share instance methods by using a hidden parameter (this).
OpenGL's API takes a pointer to an array so it would have to be an array to be defined. You'd have 2 comparisons in that solution though, just for accessing an index (I don't think any compiler creates a jump table for 2 cases, even than you would need a comparison or 2 for the default case) which compared to an indexed array would be slower. Though not really concerned about the operator[] so much as defined behavior to be compatible with opengl.
@ cire
Both just thinking off the top of my head, I think Microsoft Directx's (can't remember how directx passes stuff to the gpu) math library is written in C (yah it's pretty nasty) and then others like GLM written in C++.
This way, the extra memory only exists temporarily and there's little risk of memory leakage, although I suppose there's a fair amount of overhead with the object construction and DMA. You would use it like this: glFoo(my_point.to_array().get());
How's that?
> Why do you need to be able to index into the vertex like an array anyway?
¿why do you need `x', `y' access?
An array is easier to extend, the algorithms just need to adjust the upper limit.
> almost every math library I see used with opengl defines a vector with variables instead of an array.
¿by instance?
Both just thinking off the top of my head, I think Microsoft Directx's (can't remember how directx passes stuff to the gpu) math library is written in C (yah it's pretty nasty) and then others like GLM written in C++.
Doesn't support it in the way std::unique_ptr<float[]> does.