What is the advantage of using union for struct and array of the same size

I read a piece of code somewhere for determining a 3d coordinate. So they used coordinates x

, y

and z

as shown below:

    union
    {
        struct
        {
            float x, y, z;
        };
        float _v[3];
    };

      

My question is why is it required here union

and also what is the advantage of using a struct with an array?

+3


source to share


3 answers


Important note: this construct leads to undefined behavior. What follows is a description of the intentions of its authors, which, unfortunately, many compilers translate into exactly the behavior that authors expect, which, in turn, leads to the distribution of such code.

Design

union

not needed here: the authors used it for convenience. The reason they put union

is to give the syntax to access x

, y

and in z

two different ways:

  • By specifying the field name , that is coord.x

    , coord.y

    or coord.z

    , or
  • By specifying the index of the field , that is coord._v[0]

    , coord._v[1]

    or coord._v[2]

    .


An approach that provides comparable functionality without using undefined is to use built-in member functions for your access:

struct Vector3D {
    int v[3];
    int& x() { return v[0]; }
    int& y() { return v[1]; }
    int& z() { return v[2]; }
};

int main() {
    Vector3D coord;
    coord.v[0] = 5;
    cout << coord.x() << endl;
    coord.y() = 10;
    cout << coord.v[1] << endl;
    return 0;
}

      

Demo version

+2


source


As Gill Bates says, this way you can (possibly) access 3 coordinates like x, y, z

and how v[0], v[1], v[2]

But as per @Richard Critten's comment, this is actually UB.

You can get the same result in a "safe" way with something like this:

struct Coordinates
{
    Coordinates():x(v[0]), y(v[1]), z(v[2])
    {
    }

    int v[3];
    int& x;
    int& y;
    int& z;
};

      



ie using references to array values ​​and initializing them in the constructor

The size of this structure will be clearly different (more) than the union you show in the OP

+4


source


This way you can address the 3d coordinate as a structure.

foo.x;
foo.y; // etc

      

But it also allows you to get 3 variables as an array, taking up the same space (at least by plan), accessing them like ...

foo._v[0] // x, etc

      

Anyway, this idea. But the moment the structure has any padding between members, your array will be offset and you will end up reading the garbage values. In short, this code has undefined behavior, a bad implementation that shouldn't be used.

+1


source







All Articles