Samaursa
Samaursa

Reputation: 17271

Union of same type in C++

Whenever I see examples of union, they are always different types. For example, from MSDN:

// declaring_a_union.cpp
union DATATYPE    // Declare union type
{
    char   ch;
    int    i;
    long   l;
    float  f;
    double d;
} var1;          // Optional declaration of union variable

int main()
{
}

What happens if I have a union (in this case anonymous, but that shouldn't matter) like this:

union
{
    float m_1stVar;
    float m_1stVarAlternateName;
};

Regardless of whether this is good practice or not, will this cause any issues?

Upvotes: 11

Views: 3485

Answers (3)

Lorah Attkins
Lorah Attkins

Reputation: 5856

This is legal and very useful in situations where you have different contexts, where different names would be more appropriate. Take a four member vector vec4 type for example (similar to what you'd find in GLSL):

vec4 v(1., 1., 1., 1.);

// 1. Access as spatial coordinates
v.x;
v.y;
v.z;
v.w;

// 2. Access as color coordinates (red, green, blue, alpha)
v.r;
v.g;
v.b; 
v.a;

// 3 Access as texture coordinates
v.s;
v.t;
v.p;
v.q;

A vec4 may only have four members of the same type, but you'd use different names to refer to the same objects, depending on the context.

Case in point, data contained in the GLM (OpenGL mathematics) vector use this feature, albeit the code is a bit more intriticate:

#       if GLM_CONFIG_XYZW_ONLY
            T x, y;
#           if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_FUNCTION
            GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(T, Q, x, y)
#           endif//GLM_CONFIG_SWIZZLE
#       elif GLM_CONFIG_ANONYMOUS_STRUCT == GLM_ENABLE
            union
            {
                struct{ T x, y; };
                struct{ T r, g; };
                struct{ T s, t; };

                typename detail::storage<2, T, detail::is_aligned<Q>::value>::type data;

#               if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR
                    GLM_SWIZZLE2_2_MEMBERS(T, Q, x, y)
                    GLM_SWIZZLE2_2_MEMBERS(T, Q, r, g)
                    GLM_SWIZZLE2_2_MEMBERS(T, Q, s, t)
                    GLM_SWIZZLE2_3_MEMBERS(T, Q, x, y)
                    GLM_SWIZZLE2_3_MEMBERS(T, Q, r, g)
                    GLM_SWIZZLE2_3_MEMBERS(T, Q, s, t)
                    GLM_SWIZZLE2_4_MEMBERS(T, Q, x, y)
                    GLM_SWIZZLE2_4_MEMBERS(T, Q, r, g)
                    GLM_SWIZZLE2_4_MEMBERS(T, Q, s, t)
#               endif
            };
#       else
            union {T x, r, s;};
            union {T y, g, t;};

#           if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_FUNCTION
                GLM_SWIZZLE_GEN_VEC_FROM_VEC2(T, Q)
#           endif//GLM_CONFIG_SWIZZLE
#       endif

Upvotes: 3

Kusal Hettiarachchi
Kusal Hettiarachchi

Reputation: 603

An issue would arise only if you want to have unique values for the two variables. In your use-case, it should work fine.

Upvotes: 0

Mark Ransom
Mark Ransom

Reputation: 308548

No, this won't cause any issues. The reason you don't see it more often is that it's pointless - both names refer to the same value of the same type.

Upvotes: 13

Related Questions