If the type of a union can be an integer, string (a character pointer), or gnumbers structure, and the union and its current type are declared in a structure, the following declaration applies:
enum utype { INTEGER=1, STRING=2, GNUMBERS=3 }; struct u_tag { enum utype utype; /* the union's discriminant */ union { int ival; char *pval; struct gnumbers gn; } uval; };
The following constructs and eXternal Data Representation (XDR) procedure serialize and deserialize the discriminated union:
struct xdr_discrim u_tag_arms[4] = { { INTEGER, xdr_int }, { GNUMBERS, xdr_gnumbers } { STRING, xdr_wrap_string }, { __dontcare__, NULL } /* always terminate arms with a NULL xdr_proc */ } bool_t xdr_u_tag(xdrs, utp) XDR *xdrs; struct u_tag *utp; { return(xdr_union(xdrs, &utp->utype, &utp->uval, u_tag_arms, NULL)); }
The xdr_gnumbers subroutine is presented in the "Passing Linked Lists Using XDR Example". The xdr_wrap_string subroutine is presented in Example D of "Example Using an XDR Array". The default arms parameter to the xdr_union parameter is NULL in this example. Therefore, the value of the union's discriminant may legally take on only values listed in the u_tag_arms array. This example also demonstrates that the elements of the arms array do not need to be sorted.
The values of the discriminant may be sparse (though not in this example). It is good practice assigning explicit integer values to each element of the discriminant's type. This practice documents the external representation of the discriminant and guarantees that different C compilers emit identical discriminant values.