Philip Stuyck
Philip Stuyck

Reputation: 7457

What is the use case for an anonymous union type

A saw a question with the following code :

union
{
     float dollars;
     int yens;
}price;

price is a variable whose type does not have a name. What is such an unnamed type useful for? Lambda expressions? Is this valid in both C and C++?

Upvotes: 3

Views: 599

Answers (6)

user3528438
user3528438

Reputation: 2817

struct FooBar
{
    union
    {
        Foo foo;
        char dummy[128];
    };
    Bar bar;
};

I've seen people use nameless unions to control the offset of struct members.

There's no trivial way to align a struct member to a certain boundary, but there are ways to align the beginning of the struct to arbitrary boundaries, then pad the member to the next boundary.

Upvotes: 0

Buni
Buni

Reputation: 251

I saw code like this in alot of mathematical libraries for 2D/3D calculation:

struct Matrix3x3
{
    union
    {
        struct
        {
            float m00 , m01 , m02;
            float m10 , m11 , m12;
            float m20 , m21 , m22;
        };

        float m[ 3 ][ 3 ];
    };
};

see also this Q


iirc, I read somewhere that using such methods leads to violating the strict aliasing rule

Upvotes: 0

Gopi
Gopi

Reputation: 19864

In C according to this link

https://gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html#Unnamed-Fields

You can just access the the member of the union like price.dollars and price.yens because price is already an variable of type union and there is no need to create a new object of same type.

union
{
     float dollars;
     int yens;
}price;

int main(void) {
    price.dollars = 90.5;
    printf("%f\n",price.dollars);
    price.yens = 20;
    printf("%d\n",price.yens);
    return 0;
}

Upvotes: 1

rghome
rghome

Reputation: 8819

I have used unions in the past as mechanisms for handling storage formats and translating between them.

For example, it could be that the program includes code for storing amounts in a a file in float format and that the storage function accepts/returns a float. Later, it is discovered we need to use an integer, so we simply use the union so access the data in the format we know it to be. For example:

price.dollars = load_from_file();
if (yen_flag)
    // use price.yen
else
    // use price.dollars

It is also commonly used for implementation independent storage of ints.

union {
    int int_val;
    char as_bytes[4];
} int_store;

Sorry if there are any syntax errors, it's been a while ...

Upvotes: 1

The fact that the type does not have a name has very little effect on the use of the price variable. All it means is that you cannot (easily) create another object of this type.

This construct makes the most sense if price is a local variable inside a function. If you only ever want one object of this type, you don't need to name the type, so why bother. It doesn't differ at all from:

union SomeNameIPromiseNotToUseAnywhereAndWhichDoesntConflictWithAnything
{
  float dollars;
  int yens;
} price;

Notice that in C++11 and beyond, you can actually create another object:

decltype(price) anotherPrice;

Upvotes: 5

utnapistim
utnapistim

Reputation: 27365

In C++, it is valid. The code defines a local variable called price, which can either store an integer value in yens or a float value in dollars.

Without seeing how it is used, I can only conclude that the variable is a local/temporary variable (and probably, in a function that attempts to do too much).

Example:

union
{
     float dollars;
     int yens;
} price;

if(currency != "USD")
    price.yens = ConvertToYEN(fullPrice);
else
    price.dollars = GetUpdatedPriceInUSD(abc, currency);

if(currency == "YEN")
   std::cout << "Using price in yens: " << price.yens << "\n";

Upvotes: 2

Related Questions