Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are pointers to members of an anonymous union equal?

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.

like image 615
ugoren Avatar asked Apr 23 '18 09:04

ugoren


People also ask

What about C++ anonymous unions and structures?

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.

What are the limitations of an anonymous union?

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

How to access the members of a Union using the Arrow?

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.

What is an anonymous union in C99 TC3?

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.


1 Answers

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.

like image 158
Marco A. Avatar answered Nov 11 '22 06:11

Marco A.