Union of same type in C++
Asked Answered
B

3

11

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?

Boutique answered 28/6, 2011 at 20:31 Comment(3)
What issues do you think this might cause?Uneasy
I am getting heap corruption, and the answer to this question will lead to another question :) ... I want to eliminate all possibilities. In this case, I don't see any issues, but as they say 'you never know'.Boutique
I guess, you are already using some tools apart from mere code inspection? On unix-likes valgrind is incredibly useful, not sure about alternatives on Windows (#413977). Finding heap corruption by code inspection can be very time-consuming.Hurley
E
13

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.

Excerpt answered 28/6, 2011 at 20:33 Comment(9)
True, but sometimes you may not know whether the types are the same (like if one of them is a template argument).Kelila
@leftaroundabout, very good point that I hadn't considered. Thanks.Excerpt
Sorry to necro this, but can this be backed up? Is it defined somewhere? Obviously it should work, but is it guaranteed?Rayon
@Rayon since it follows the required syntax, the only way it wouldn't work is if it were specifically disallowed. I've never been much of a language lawyer, so I'm not really keen to search the standard for something that probably isn't there.Excerpt
I should have specified: Will there be a problem if I write to the first field, and read from the second? I was going to ask this question, but I'm pretty sure it would be closed, being a duplicate of this.Rayon
@Rayon I've heard that writing to one element of a union and reading from another is actually undefined behavior, although you might get away with it.Excerpt
@Rayon can you link your posted questionCharleen
@Charleen #34677843Rayon
@Rayon Your question is different. This one doesn't have structs.Christinchristina
B
3

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
Blount answered 28/10, 2020 at 22:15 Comment(0)
A
0

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

Aeneus answered 3/10, 2019 at 6:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.