{"id":7783,"date":"2026-10-10T00:01:42","date_gmt":"2026-10-10T07:01:42","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=7783"},"modified":"2026-10-03T14:23:09","modified_gmt":"2026-10-03T21:23:09","slug":"tagging-a-union","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=7783","title":{"rendered":"Tagging a Union"},"content":{"rendered":"<p>A union by itself presents some issues, which is why unions are flagged as insecure. I&#8217;ve shown some examples in <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=7795\">last week&#8217;s Lesson<\/a>. But there is a solution that provides a backstop for consistency when accessing the different data types stored as union members.<br \/>\n<!--more--><br \/>\nI received a few slaps on LinkedIn when I shared the <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=7784\">&#8220;Back When Unions Were Useful&#8221;<\/a> post a few weeks back. Apparently, modern C code still uses a union in many instances. Active C programmers descended upon my post with ample vigor. The key that keeps a union usable and necessary is that the union&#8217;s data must be <em>tagged<\/em>.<\/p>\n<p>The process of tagging a union involves coordinating a union&#8217;s contents with an enumerated list of data types. The list of data types determines how the union&#8217;s data is accessed. As an example, consider this union:<\/p>\n<p><code>union values {<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;char ch[8];<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;long li;<br \/>\n};<\/code><\/p>\n<p>The <em>values<\/em> union has storage for <em>char<\/em> variable <code>ch<\/code> as an 8-character array or string. Also present is a <em>long int<\/em>, <code>li<\/code>. Both of these items share their storage, which is a point of contention.<\/p>\n<p>To tag these items, an enumerated list is coupled to the union. In the enumeration, the data types are represented as constant values:<\/p>\n<p><code>enum {<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;TYPE_STRING,<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;TYPE_LONG<br \/>\n};<\/code><\/p>\n<p>The <em>enum<\/em> keyword creates two constants, <code>TYPE_STRING<\/code> and <code>TYPE_LONG<\/code>. These constants are assigned values 0 and 1 by the compiler, which is <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=1440\">how enumeration works<\/a>. The point is to relate these constants to the union&#8217;s data types. This pairing is creates the tags.<\/p>\n<p>The enum and the union are married within a structure: the constants are the tags, and the union&#8217;s data is the payload. This design keeps data aligned, with the tags serving as a reference to ensure that the proper values stored in the union are recognized. The following code shows an example:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2026_10_10-Lesson.c\" rel=\"noopener\" target=\"_blank\">2026_10_10-Lesson.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;string.h&gt;\r\n\r\n<span class=\"comments\">\/* tagged union definition *\/<\/span>\r\nstruct u_data {\r\n    <span class=\"comments\">\/* tags *\/<\/span>\r\n    enum {\r\n        TYPE_STRING,\r\n        TYPE_LONG\r\n    } data_type;\r\n    <span class=\"comments\">\/* payload *\/<\/span>\r\n    union values {\r\n        char ch[8];\r\n        long li;\r\n    } v;\r\n};\r\n\r\n<span class=\"comments\">\/* generate output based on tag *\/<\/span>\r\nvoid output(struct u_data d)\r\n{\r\n    switch(d.data_type)\r\n    {\r\n        case TYPE_STRING:\r\n            printf(\"String value is: %s\\n\",d.v.ch);\r\n            break;\r\n        case TYPE_LONG:\r\n            printf(\"Long int value: %li\\n\",d.v.li);\r\n            break;\r\n        default:\r\n            printf(\"Unknown data type\\n\");\r\n    }\r\n}\r\n\r\nint main()\r\n{\r\n    struct u_data data;\r\n\r\n    <span class=\"comments\">\/* set data type tag and data *\/<\/span>\r\n    data.data_type = TYPE_STRING;\r\n    strcpy(data.v.ch,\"Hello!\");\r\n\r\n    <span class=\"comments\">\/* output proper data *\/<\/span>\r\n    output(data);\r\n\r\n    return 0;\r\n}<\/pre>\n<p>The code starts with the tagged union structure definition. The <em>u_data<\/em> structure contains enumerated constants <em>data_type<\/em> and union <em>values<\/em>. The constant names in the enumeration pair with the data types stored in the union.<\/p>\n<p>The <em>output()<\/em> function swallows a <em>u_data<\/em> structure as its argument, referenced as <code>d<\/code> within the function. A <em>switch-case<\/em> structure evaluates the <code>d.data_type<\/code> member in the structure, which reflects the enumerated constant for the data type requested. Each <em>case<\/em> statement matches the data types. A <em>printf(<\/em>) statement outputs the data properly based on the tag presented:<\/p>\n<ul>\n<li><code>d.v.ch<\/code> is the structure member for a string. <code>d<\/code> is the structure passed to the <em>output()<\/em> function. <code>v<\/code> is the union stored in the structure. <code>ch<\/code> is the string stored in the union.<\/li>\n<li><code>d.v.li<\/code> is the structure member for a <em>long int<\/em>. <code>d<\/code> is the structure passed to the <em>output()<\/em> function. <code>v<\/code> is the union stored in the structure. <code>li<\/code> is the <em>long<\/em> integer stored in the union.<\/li>\n<\/ul>\n<p>The <em>main()<\/em> function creates a <em>u_data<\/em> structure named <code>data<\/code>: <code>struct u_data data;<\/code><\/p>\n<p>Before a value is set in the union, a tag is assigned:<\/p>\n<p><code>data.data_type = TYPE_STRING;<\/code><\/p>\n<p>This tag helps the programmer and the code to identify the union&#8217;s data as a string. Next, the string is assigned:<\/p>\n<p><code>strcpy(data.v.ch,\"Hello!\");<\/code><\/p>\n<p>Finally, a call is made to the <em>output()<\/em> function to properly deal with the union&#8217;s contents:<\/p>\n<pre>String value is: Hello!<\/pre>\n<p>Tags work to ensure that union data is accurately interpreted. Like many other aspects of C programming, adhering to this rule is up to the programmer; the compiler doesn&#8217;t check for consistency with regards to data stored in a union, which is a point I&#8217;ve been driving home for the past few weeks. But if you assign tags and use them, unions present an interesting and useful solution to many coding problems.<\/p>\n<p>By the way, if you change the code in the <em>main()<\/em> function to read:<\/p>\n<p><code>data.data_type = TYPE_LONG;<\/code><\/p>\n<p>The output reads:<\/p>\n<pre>Long int value: 36762444129608<\/pre>\n<p>Again, the code runs properly only when the programmer is paying attention.<\/p>\n<p>Next week, I continue my exploration of unions by exploiting their primary weakness.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Unions are useful and safe, providing that you know how to tag the data. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=7783\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-7783","post","type-post","status-publish","format-standard","hentry","category-main"],"_links":{"self":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/7783","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=7783"}],"version-history":[{"count":9,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/7783\/revisions"}],"predecessor-version":[{"id":7827,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/7783\/revisions\/7827"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=7783"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=7783"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=7783"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}