Reputation: 7457
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
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
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 ];
};
};
iirc, I read somewhere that using such methods leads to violating the strict aliasing rule
Upvotes: 0
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
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
Reputation: 171127
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
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