Type Attribute transparent_union

Linux The transparent_union attribute applied to a union definition or a union typedef indicates the union can be used as a transparent union. Whenever a transparent union is the type of a function parameter and that function is called, the transparent union can accept an argument of any type that matches that of one of its members without an explicit cast. Arguments to this function parameter are passed to the transparent union, using the calling convention of the first member of the union type. Because of this, all members of the union must have the same machine representation. Transparent unions are useful in library functions that use multiple interfaces to resolve issues of compatibility. The language feature is an orthogonal extension to C89, C99, and Standard C++, and has been implemented to facilitate porting programs originally developed with GNU C.

The type attribute must follow the closing brace of the union or typedef definition.

union u_t {
   int a;
   short b;
   char c;
} __attribute__((__transparent_union__)) U; 
 
typedef union {
   int *iptr;
   union u2_t *u2ptr;
} status_ptr_t  __attribute__((__transparent_union__)); 

Type attribute transparent_union can be applied to anonymous unions with tag names.

When type attribute transparent_union is applied to the outer union of a nested union, the size of the inner union (that is, its largest member) is used to determine if it has the same machine representation as the other members of the outer union. For example,

union u_t {
   union u2_t {
      char a;
      short b;
      char c;
      char d;
   };
   int a;
} __attribute__((__transparent_union__));

attribute transparent_union is ignored because the first member of union u_t, which is itself a union, has a machine representation of 2 bytes, whereas the other member of union u_t is of type int, which has a machine representation of 4 bytes.

The same rationale applies to members of a union that are structures. When a member of a union to which type attribute transparent_union has been applied is a struct, the machine representation of the entire struct is considered, rather than members.

Restrictions

The union must be a complete union type

All members of the union must have the same machine representation as the first member of the union. This means that all members must be representable by the same amount memory as the first member of the union. The machine representation of the first member represents the maximum memory size for any remaining union members. For instance, if the first member of a union to which type attribute transparent_union has been applied is of type int, then all following members must be representable by at most 4 bytes. Members that are representable by 1, 2, or 4 bytes are considered valid for this transparent union.

The first member of the union cannot be a floating-point type (float, double, float _Complex, or double _Complex) or a Vector type. However, float _Complex, double _Complex, and Vector types can be members of a transparent union, as long as they are not the first member. The restriction that all members of the transparent union have the same machine representation as the first member still applies.

Examples

This example shows how attribute transparent_union can be applied to a function parameter declaration:

void foo( union u_t { int a; short b; char c;} __attribute__((transparent_union)) uu) 
{
   printf("uu.b is %d\n",uu.b);
}
 
int main() {
   short s = 99;
   foo(s);
   return 0;
}

This example shows how Complex types can be members of a transparent union:

union u_t {
   int i[2];      // This member must has a machine representation of 8 bytes.
   float _Complex cf;
} __attribute__((__transparent_union__)) U;
 
void foo(union u_t uu) {
   printf("uu.cf is %f\n",uu.cf);
}
 
int main() {
   float _Complex my_cf = 5.0f + 1.0f * __I;
   foo(my_cf);
   return 0; 
}
IBM Copyright 2003