Is this a valid usage for unions?

Started by
15 comments, last by Ravyne 11 years, 11 months ago
Hello all,

recently I decided to discard my hand-written math library code and use the GLM library.

Because I want to make it "feel" like my own code need some thin wrapper around it. Because performance matters I don't want to
write the wrapper using inheritance like this:


class Vector3 : public glm::dvec3
{
};


Now I have the idea to use a union and write code like this:


union Vector3
{
public:
Vector3(double x, double y, double z)
: v(x, y, z)
{
}

double x, y, z;

private:
glm::dvec3 v;
};


Is this valid code (using C++11)?
Advertisement
Access to members of a virtual base and calling virtual functions will typically result in a small performance penalty, but in the kind of inheritance you've shown, there will be none.

The doubles x, y and z in your union all occupy the same memory location. Presumably that's not intended.

I also suspect that you're heading down the road of type punning through the union, which strictly speaking is illegal, though some compilers explicitly support it. Take care.

My recommendation: typedef glm::dvec3 Vector3;
Partially answering myself.

of course
double x, y, z
does not work.

So I have to use something like this:

union Vector3
{
public:
Vector3(double x, double y, double z)
: v(x, y, z)
{
}
inline double x() { return d[0]; }
inline double y() { return d[1]; }
inline double z() { return d[2]; }

private:
double d[3];
glm::dvec3 v;
};


Actually I wanted to avoid the method calls for accessing the data members...

Are compilers smart enough to optimize this code (this post) so that it performs as fast as the first one (previous post)?
Using
typedef glm::dvec3 Vector3
was my first idea BUT I want things like the cross product to be used as member functions. GLM implements them as
normal functions taking the two vectors as parameters.

But when the inheritance I have suggested does not have any performance penalties I will go that way.


GLM implements them as normal functions taking the two vectors as parameters.


That makes perfect sense I'd say; as a cross product is a pure function, to have it appear to "act upon" any particular vector would be strange. A cross product also has no need to access or manipulate the (non-existent) private state of a vector. Free functions also play nicer with generic code, FWIW.
Ok for the cross product it makes sense. But normalize?
Same reasoning (IMO). One input, one output, no dependency on the private state.
I don't think you want to be using a union here, it might work one way or another, but I can't see this as being considered good practice

I'd just go with the inheritance if you want to add some of your own functions, I can assure you that the "performance penalty" that could possibly be introduced by it will be least of your worries in the end. Otherwise go for the typedef, clean and simple.

By the way, only worry about optimizing these little things like inheritance overhead if they actually pose a problem, and in this case it'll probably never become a problem. In the end there will be loads of better candidates for optimization before you should even consider looking at overhead caused by language mechanisms.

I gets all your texture budgets!


Same reasoning (IMO). One input, one output, no dependency on the private state.

I think you are right, at least if normalize creates a new vector. But when I really want to normalize the instance normalize is invoked on, it needs access to the state. But maybe that is not the problem as the state is public...



I don't think you want to be using a union here, it might work one way or another, but I can't see this as being considered good practice

"Good practice" is enough of a reason for me to not use unions for this smile.png

So decision has to be made between "inheritance" and "typedef + free functions"
You might want to look at the coding style for the rest of your code (I assume you're writing a game?) and adapt to what fits best with that so you can save yourself the headache of having to keep different coding styles in mind later on

If there's no other code to speak of and if you're comfortable with it I'd say go with edd's suggestion.

I gets all your texture budgets!

This topic is closed to new replies.

Advertisement