C++11 allows an anonymous union to be defined in a function, and its members can be accessed as variables of the function. If I examine the pointers to the different members, they are the same, but the ==
operator says they're unequal.
Such strange behavior is typically the result of undefined behavior, but I don't see anything undefined in my code (I made sure to that both members are of the same type).
The behavior is different if I use a named variable of an unnamed union type. In this case, the pointers compare equal.
This program demonstrates both cases:
#include <iostream>
using namespace std;
#ifdef NAMED
// Create a named object of a union type
#define NAME n
#define ADDR(mem) &(NAME.mem)
#else
// Create an anonymous union in main()
#define NAME
#define ADDR(mem) &mem
#endif
int main()
{
union {
int a;
int b;
} NAME;
cout << "&a = " << ADDR(a) << endl;
cout << "&b = " << ADDR(b) << endl;
cout << "(&a==&b) = " << (ADDR(a) == ADDR(b)) << endl;
return 0;
}
When compiled with -DNAMED
it prints to identical pointers, and 1 (equal pointers). Without -DNAMED
, it again prints identical pointers, but then 0 (unequal pointers).
Tested with g++ 5.4.0, Ubuntu 16.04, x86_64.
What about C++? Anonymous Unions and Structures are NOT part of C++ 11 standard, but most of the C++ compilers support them. Since this is a C only feature, the C++ implementations don’t allow to anonymous struct/union to have private or protected members, static members, and functions.
An anonymous union cannot have protected or private members, and it cannot have member functions. A global or namespace anonymous union must be declared with the keyword static. Related information The static storage class specifier
The arrow operator ( ->) is used for accessing the members using pointer. We have pointers to unions and can access members using the arrow operator (->) just like structures. The following program shows the usage of pointers to union in C programming − Consider the same example with different input.
Before C99 TC3 (DR 283) this behaviour was undefined, but commonly implemented this way. Similar to struct, an unnamed member of a union whose type is a union without name is known as anonymous union. Every member of an anonymous union is considered to be a member of the enclosing struct or union.
Your address checking is well defined (as YSC pointed out) and the standard guarantees that all members shall have the same address (cfr. [class.union]/3).
You must have stumbled upon a now fixed compiler bug.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With