<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Paul J. Lucas</title>
    <description>The latest articles on DEV Community by Paul J. Lucas (@pauljlucas).</description>
    <link>https://dev.to/pauljlucas</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2304%2F7366785.jpeg</url>
      <title>DEV Community: Paul J. Lucas</title>
      <link>https://dev.to/pauljlucas</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pauljlucas"/>
    <language>en</language>
    <item>
      <title>A Simple Dynamic Array for C</title>
      <dc:creator>Paul J. Lucas</dc:creator>
      <pubDate>Sat, 30 May 2026 01:07:55 +0000</pubDate>
      <link>https://dev.to/pauljlucas/a-simple-dynamic-array-for-c-1k24</link>
      <guid>https://dev.to/pauljlucas/a-simple-dynamic-array-for-c-1k24</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;When many programmers get inspired to implement a dynamic array (meaning an array that grows automatically as new elements are appended) in C, they often try to incorporate the element’s type into the array.  Since C lacks a template facility like C++, that often means (ab)using &lt;a href="https://dev.to/pauljlucas/cc-preprocessor-macros-fh5"&gt;macros&lt;/a&gt; like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#define TYPED_ARRAY(TYPE)                            \
  typedef struct TYPE##_array TYPE##_array;          \
  struct TYPE##_array {                              \
    TYPE  *elements;                                 \
    size_t len;                                      \
    size_t cap;                                      \
  };                                                 \
  static void TYPE##_array_init( TYPE##_array *a ) { \
    *a = (TYPE##_array){ 0 };                        \
  }                                                  \
  &lt;/span&gt;&lt;span class="cm"&gt;/* ... and several more functions ... */&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The problems with (ab)using macros like this for typed arrays in C are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;They’re difficult to write and maintain.&lt;/li&gt;
&lt;li&gt;The entire implementation must be in the header (leading to increased compilation times and code bloat).&lt;/li&gt;
&lt;li&gt;Error messages involving macros are often very difficult to read.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Instead of trying to shoehorn typed arrays via macros like this into C, let’s try to implement the simplest possible dynamic array in C.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Simple Dynamic Array
&lt;/h2&gt;

&lt;p&gt;Here’s a fairly simple structure for a dynamic array:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt; &lt;span class="n"&gt;array_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt;   &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Pointer to array of elements.&lt;/span&gt;
  &lt;span class="kt"&gt;size_t&lt;/span&gt;  &lt;span class="n"&gt;esize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;     &lt;span class="c1"&gt;// Size of an element.&lt;/span&gt;
  &lt;span class="kt"&gt;size_t&lt;/span&gt;  &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;       &lt;span class="c1"&gt;// Length of array.&lt;/span&gt;
  &lt;span class="kt"&gt;size_t&lt;/span&gt;  &lt;span class="n"&gt;cap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;       &lt;span class="c1"&gt;// Capacity of array.&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of somehow trying to incorporate element type information, we’re just going to do the simplest thing and use an element’s size in bytes and treat elements as opaque chunks of memory.  We’ll leave how to interpret those bytes as a type to the user.  The rest of the members should be self explanatory.  &lt;/p&gt;

&lt;p&gt;The primary functions needed are for initialization, clean-up, appending elements, and accessing elements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Initialization &amp;amp; Clean-Up
&lt;/h3&gt;

&lt;p&gt;Initialization is trivial:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;array_init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;array_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;esize&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;array_t&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;esize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;esize&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;em&gt;designated initializer&lt;/em&gt; &lt;code&gt;.esize&lt;/code&gt; sets the element’s size; the other members are initialized to zero (or equivalent).  If you wanted an array of &lt;code&gt;int&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;array_t&lt;/span&gt; &lt;span class="n"&gt;int_array&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;array_init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;int_array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clean-up, while not trivial, is still straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="nf"&gt;void&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;array_free_fn_t&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;array_cleanup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;array_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;array_free_fn_t&lt;/span&gt; &lt;span class="n"&gt;free_fn&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;free_fn&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;free_fn&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;esize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;elements&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;array_init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;esize&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A clean-up function is needed for elements that require their own clean-up, e.g., strings.  The conversion to &lt;code&gt;char*&lt;/code&gt; is needed since arithmetic can’t be done on pointers in standard C.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accessing Elements
&lt;/h3&gt;

&lt;p&gt;To access an element at a given index, we can implement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;array_at_nc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;array_t&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;elements&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;esize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;array_at&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;array_t&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;len&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;array_at_nc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;_nc&lt;/code&gt; version is for “no check,” i.e., does no bounds-checking.  If you’re iterating, the &lt;code&gt;_nc&lt;/code&gt; version is fine since the index is guaranteed to be &amp;lt; &lt;code&gt;len&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;int_array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;array_at_nc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;int_array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Appending Elements
&lt;/h3&gt;

&lt;p&gt;To append an element, we can implement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;array_push_back&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;array_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;array_reserve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;array_at_nc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’ll get to &lt;code&gt;array_reserve&lt;/code&gt; shortly, but, in the mean time, notice that &lt;code&gt;array_push_back&lt;/code&gt; does &lt;em&gt;not&lt;/em&gt; take the element to be appended; instead, for simplicity, it merely makes room for the element and returns a pointer to the raw memory for it at which point the user can assign to it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;array_push_back&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;int_array&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After all, the core functionality of a dynamic array is only to grow when necessary; we leave dealing with the typed elements to the user.  This is similar in spirit to the standard library functions of &lt;a href="https://en.cppreference.com/c/algorithm/qsort" rel="noopener noreferrer"&gt;&lt;code&gt;qsort&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://en.cppreference.com/c/algorithm/bsearch" rel="noopener noreferrer"&gt;&lt;code&gt;bsearch&lt;/code&gt;&lt;/a&gt; that implement only core functionality (sorting and searching, respectively) leaving the elements to the user.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;array_reserve&lt;/code&gt; function is where most of the “meat” is. It reserves space for &lt;code&gt;res_len&lt;/code&gt; additional elements.  A naive implementation would grow the array by &lt;em&gt;exactly&lt;/em&gt; &lt;code&gt;res_len&lt;/code&gt; elements.  The problem with that is if you (a) don’t know how many elements there will be in advance (which is often the case) and (b) append elements one by one, it would call &lt;a href="https://en.cppreference.com/c/memory/realloc" rel="noopener noreferrer"&gt;&lt;code&gt;realloc&lt;/code&gt;&lt;/a&gt; that, not only has to reallocate the array, but also &lt;a href="https://en.cppreference.com/c/string/byte/memcpy" rel="noopener noreferrer"&gt;&lt;code&gt;memcpy&lt;/code&gt;&lt;/a&gt; the elements every time — which is &lt;em&gt;really&lt;/em&gt; expensive, specifically, runs in O(&lt;em&gt;n&lt;/em&gt;&lt;sup&gt;2&lt;/sup&gt;) time.&lt;/p&gt;

&lt;p&gt;Instead, we grow the array by at &lt;em&gt;least&lt;/em&gt; &lt;code&gt;res_len&lt;/code&gt; additional elements, specifically &lt;em&gt;1.5n&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#define ARRAY_CAP_MIN  4  &lt;/span&gt;&lt;span class="cm"&gt;/* Minimum array capacity. */&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="n"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;array_reserve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;array_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;res_len&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;res_len&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;cap&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;len&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;cap&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;cap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ARRAY_CAP_MIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;min_cap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;len&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;res_len&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;cap&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;min_cap&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;cap&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;cap&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;      &lt;span class="c1"&gt;// grow by ~1.5x&lt;/span&gt;
  &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;elements&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;realloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;cap&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;esize&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While this has the potential to waste memory (more in a bit), the benefit is that the expense of reallocation exponentially decreases over time and so each append is &lt;a href="https://en.wikipedia.org/wiki/Amortized_analysis" rel="noopener noreferrer"&gt;amortized&lt;/a&gt; to O(1).&lt;/p&gt;

&lt;p&gt;Why 1.5 instead of 2?  The problem with 2 is that doubling the size of each new allocation is always greater than the sum of all previous allocations combined, which means &lt;code&gt;realloc&lt;/code&gt; can’t reuse even a block coalesced from previous allocations.  For example, assuming previous allocations of 4, 8, and 16 (summing to 28), the next allocation will be 32, but 32 &amp;gt; 28, so &lt;code&gt;realloc&lt;/code&gt; can’t reuse that block.&lt;/p&gt;

&lt;p&gt;In contrast, growing by 1.5x yields allocations 4, 6, and 9 (summing to 19), and the next allocation will be 13, and 13 ≤ 19, so &lt;code&gt;realloc&lt;/code&gt; &lt;em&gt;can&lt;/em&gt; reuse that block; hence 1.5x is easier on the memory allocator by reducing fragmentation.  Additionally, growing by 1.5x wastes at most 33% of allocated memory whereas 2x wastes at most 50%.&lt;/p&gt;

&lt;p&gt;The use of &lt;code&gt;ARRAY_CAP_MIN&lt;/code&gt; having a value of 4 eliminates the expensive initial size increases (that would start out as 2, 3, and 4).&lt;/p&gt;

&lt;h3&gt;
  
  
  Other Functions
&lt;/h3&gt;

&lt;p&gt;The functions &lt;code&gt;array_init&lt;/code&gt;, &lt;code&gt;array_reserve&lt;/code&gt;, &lt;code&gt;array_push_back&lt;/code&gt;, and &lt;code&gt;array_cleanup&lt;/code&gt; are all you &lt;em&gt;really&lt;/em&gt; need for a dynamic array.  For convenience, you could also add functions like &lt;code&gt;array_back&lt;/code&gt;, &lt;code&gt;array_front&lt;/code&gt;, &lt;code&gt;array_pop_back&lt;/code&gt;, &lt;code&gt;array_qsort&lt;/code&gt;, and &lt;code&gt;array_bsearch&lt;/code&gt;.  Those, if wanted, are left as exercises for the reader.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding Type Information
&lt;/h2&gt;

&lt;p&gt;Now that we’ve got a nice, small, and efficient implementation of a dynamic array, it turns out that it &lt;em&gt;is&lt;/em&gt; possible to add type information thus making the dynamic array type-safe by using just a few &lt;em&gt;small&lt;/em&gt; macros.&lt;/p&gt;

&lt;p&gt;As far as I know, the following technique was invented by &lt;a href="https://danielchasehooper.com/posts/typechecked-generic-c-data-structures/" rel="noopener noreferrer"&gt;Daniel Hooper&lt;/a&gt;.  The trick is to put a generic data type of interest (here, &lt;code&gt;array&lt;/code&gt;) inside an anonymous &lt;a href="https://dev.to/pauljlucas/unions-in-c-1ojj"&gt;&lt;code&gt;union&lt;/code&gt;&lt;/a&gt; with a pointer to the desired element type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#define typed_array(TYPE) \
  union { array_t array; TYPE *ptr_type; }
&lt;/span&gt;
&lt;span class="n"&gt;typed_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;int_array&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By using a &lt;code&gt;union&lt;/code&gt;, &lt;code&gt;ptr_type&lt;/code&gt; takes up no additional space.  It’s also never written to nor read from: it exists only to provide type information at &lt;em&gt;compile-time&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why &lt;code&gt;TYPE*&lt;/code&gt; and not just &lt;code&gt;TYPE&lt;/code&gt;?  Because (a) &lt;code&gt;TYPE*&lt;/code&gt; is sufficient and (b) &lt;code&gt;sizeof(TYPE*)&lt;/code&gt; is just the size of a pointer that’s always less than &lt;code&gt;sizeof(array_t)&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Given such a &lt;code&gt;union&lt;/code&gt;, we can now implement additional wrapper macros for &lt;code&gt;array&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#define typed_array_init(ARRAY) \
  array_init( &amp;amp;(ARRAY)-&amp;gt;array, sizeof( *(ARRAY)-&amp;gt;ptr_type ) )
&lt;/span&gt;
&lt;span class="cp"&gt;#define typed_array_push_back(ARRAY) \
  (typeof((ARRAY)-&amp;gt;ptr_type))array_push_back( &amp;amp;(ARRAY)-&amp;gt;array )
&lt;/span&gt;
&lt;span class="cp"&gt;#define typed_array_at_nc(ARRAY,INDEX) \
  (typeof((ARRAY)-&amp;gt;ptr_type))array_at_nc( &amp;amp;(ARRAY)-&amp;gt;array, (INDEX) )
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Obviously, these macros require &lt;a href="https://dev.to/pauljlucas/typeof-in-c23-55p2"&gt;&lt;code&gt;typeof&lt;/code&gt;&lt;/a&gt; from &lt;a href="https://en.wikipedia.org/wiki/C23_(C_standard_revision)" rel="noopener noreferrer"&gt;C23&lt;/a&gt;, but &lt;code&gt;typeof&lt;/code&gt; has also been supported by gcc and clang as an extension to older C versions for some time.&lt;/p&gt;

&lt;p&gt;Given those macros, we can now do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;typed_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;int_array&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;typed_array_init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;int_array&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;typed_array_push_back&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;int_array&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;that eliminates the explicit use of &lt;code&gt;sizeof&lt;/code&gt; as well as all the casts.  Optionally, you can add even more macros for pointer iteration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#define typed_array_type(ARRAY)  typeof( *(ARRAY)-&amp;gt;ptr_type )
&lt;/span&gt;
&lt;span class="cp"&gt;#define typed_array_begin(ARRAY) (ARRAY)-&amp;gt;array.elements
&lt;/span&gt;
&lt;span class="cp"&gt;#define typed_array_end(ARRAY) \
  typed_array_at_nc( (ARRAY), (ARRAY)-&amp;gt;array.len )
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;typed_array_type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ia&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;typed_array_begin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ia&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;typed_array_end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ia&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s"&gt;"%d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Caveat
&lt;/h3&gt;

&lt;p&gt;One caveat with &lt;code&gt;typed_array&lt;/code&gt;, specifically with its use of an anonymous union, is that C doesn’t consider anonymous unions (or structures) the same type even when their members are identical:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;typed_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;typed_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// error: assigning incompatible type&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, you can use &lt;code&gt;typedef&lt;/code&gt; to &lt;em&gt;make&lt;/em&gt; them the same type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="n"&gt;typed_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;int_array&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;int_array&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;int_array&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// OK now&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verbosity
&lt;/h3&gt;

&lt;p&gt;If you think having to spell out &lt;code&gt;typed_array&lt;/code&gt; all the time is too verbose, you could rename &lt;code&gt;array&lt;/code&gt; to be something like &lt;code&gt;vp_array&lt;/code&gt; (&lt;code&gt;void&lt;/code&gt; pointer array) and then just name &lt;code&gt;typed_array&lt;/code&gt; as &lt;code&gt;array&lt;/code&gt;, especially if you always plan to use the typed version.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Personally, I find that the dynamic array implementation shown here exemplifies the &lt;a href="https://en.wikipedia.org/wiki/Less_is_more" rel="noopener noreferrer"&gt;less is more&lt;/a&gt; principle and keeps in the spirit of C.  I’ve used &lt;code&gt;array&lt;/code&gt; in my &lt;a href="https://github.com/paul-j-lucas/include-tidy" rel="noopener noreferrer"&gt;&lt;code&gt;include-tidy&lt;/code&gt;&lt;/a&gt; project and it works just fine.&lt;/p&gt;

&lt;p&gt;If you really want a type-safe version, it’s easily added on as an extra.  Keeping it as an extra rather than trying to incorporate type information directly into &lt;code&gt;array&lt;/code&gt; keeps the two layers nicely separated and makes each simpler.&lt;/p&gt;

</description>
      <category>c</category>
    </item>
    <item>
      <title>My Impression of AI in Programming</title>
      <dc:creator>Paul J. Lucas</dc:creator>
      <pubDate>Sun, 24 May 2026 14:47:19 +0000</pubDate>
      <link>https://dev.to/pauljlucas/my-impression-of-ai-in-programming-33ci</link>
      <guid>https://dev.to/pauljlucas/my-impression-of-ai-in-programming-33ci</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In a &lt;a href="https://dev.to/pauljlucas/include-tidy-a-tool-to-enforce-include-what-you-use-20mh"&gt;previous post&lt;/a&gt;, I wrote the following about using AI in developing my new tool &lt;a href="https://github.com/paul-j-lucas/include-tidy" rel="noopener noreferrer"&gt;&lt;code&gt;include-tidy&lt;/code&gt;&lt;/a&gt; (Tidy) that uses &lt;a href="https://clang.llvm.org/docs/LibClang.html" rel="noopener noreferrer"&gt;Libclang&lt;/a&gt;, a library I’d never used before:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What helped a &lt;em&gt;lot&lt;/em&gt; was using AI (strictly speaking, an LLM), specifically Google’s Gemini (because I’m too cheap to pay for Claude, especially for a personal project that I have no intention of making any money from). While I may write a follow-up blog post describing my experience, I’ll state briefly that AI saved me from having to read a lot of the documentation, read the tutorials, post questions to a mailing list or Stack Overflow, and wait for answers (if any).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is that aforementioned follow-up blog post.  If you’ve been using AI for a while, none of what follows will likely be a surprise to you. Prior to using AI for Tidy, I’d only used it for small functions or to ask corner-case questions.  Using it for Tidy was my first “big” use of AI.&lt;/p&gt;

&lt;p&gt;If this is your first encounter with my blog or me, you might be wondering “Who is this guy, and why should I care what he thinks?”  I’ve been tinkering with computers for over four decades, both as a &lt;a href="https://dev.to/pauljlucas/career-retrospective-1ojp"&gt;hobby and professionally&lt;/a&gt;.  Some programmers, especially those from older generations, are pretty skeptical about AI — often referring to it as “autocorrect on steroids.”  While there’s a grain of technical truth to that, it’s still pretty impressive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prompting
&lt;/h2&gt;

&lt;p&gt;While I think the term “prompt engineering” and its related “Prompt Engineer” title are vastly over-inflated (with the latter being along the lines of “Sanitation Engineer”), you &lt;em&gt;do&lt;/em&gt; have to be &lt;em&gt;detailed&lt;/em&gt; and &lt;em&gt;specific&lt;/em&gt; — just like you would be if you were submitting a question on &lt;a href="https://stackoverflow.com" rel="noopener noreferrer"&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Unlike Stack Overflow, you won’t be chastised for asking a question that’s been asked before nor for not reading the FAQ; you won’t be questioned as to why on Earth you would want to do that; you won’t get a condescending answer or comment; you won’t &lt;em&gt;not&lt;/em&gt; get an answer; and you’ll get an answer in several seconds.&lt;/p&gt;

&lt;p&gt;While all that sound great, the answer you get might be completely wrong.  A couple of times, Gemini said I should use an API function that doesn’t exist.  After me pointing that out, it did correct itself, however.&lt;/p&gt;

&lt;p&gt;Also, the answer you get is often only based on your &lt;em&gt;exact&lt;/em&gt; question. It’s probably best if you think of using AI like using a &lt;a href="https://en.wikipedia.org/wiki/The_Monkey%27s_Paw" rel="noopener noreferrer"&gt;monkey’s paw&lt;/a&gt; lest you get responses that &lt;em&gt;technically&lt;/em&gt; satisfy your request, but with &lt;a href="https://www.wired.com/story/thousands-of-vibe-coded-apps-expose-corporate-and-personal-data-on-the-open-web/" rel="noopener noreferrer"&gt;unintended consequences&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For an example, here’s my very first prompt to Gemini to create Tidy:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Write a program using clang's API that, given either a C or C++ source file, prints every symbol (macro, constant, function, type, variable, etc.) and the file and line number where that symbol was declared, or "unknown" if it can not be determined.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And it printed out a few screens’ worth of C code showing what file from Libclang to &lt;code&gt;#include&lt;/code&gt;, what functions to call to initialize and clean-up Libclang, how to parse a source file and iterate over its &lt;a href="https://en.wikipedia.org/wiki/Abstract_syntax_tree" rel="noopener noreferrer"&gt;abstract syntax tree&lt;/a&gt; (AST). Sure, I could have ready Libclang’s &lt;a href="https://clang.llvm.org/docs/LibClang.html" rel="noopener noreferrer"&gt;tutorial&lt;/a&gt;, but Gemini’s response was tailored to what I wanted to do.&lt;/p&gt;

&lt;p&gt;Of course the program it generated was nowhere near complete.  It didn’t handle command-line options, configuration files, errors, colored output, or all the corner cases when analyzing C or C++ source files.  These things would be fleshed out in the coming weeks.  But I was off to a good start.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mundane Tasks
&lt;/h2&gt;

&lt;p&gt;One other nice thing about using AI is that you can have it do mundane code that you &lt;em&gt;could&lt;/em&gt; do, but don’t want to be bothered because the code is boring.  For example, Tidy needs to pre-scan command-line arguments looking for those preceded by &lt;code&gt;-Xtidy&lt;/code&gt; to split them into two arrays: those that are Tidy-specific and those that should be passed along as-is to Libclang.  Here was my prompt:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Given &lt;code&gt;argc&lt;/code&gt; and &lt;code&gt;argv&lt;/code&gt; for &lt;code&gt;main&lt;/code&gt; in a C program, there are two types of options: (1) An &lt;code&gt;-Xtidy&lt;/code&gt; option, that is an option with &lt;code&gt;-Xtidy&lt;/code&gt; preceding it; and (2) Just an option. "Option" is either a short option or a long option.&lt;/p&gt;

&lt;p&gt;I want to manipulate &lt;code&gt;argc&lt;/code&gt; and &lt;code&gt;argv&lt;/code&gt; such that all options that are preceded by &lt;code&gt;-Xtidy&lt;/code&gt; are split off into a separate &lt;code&gt;tidy_argv&lt;/code&gt; array along with &lt;code&gt;tidy_argc&lt;/code&gt; leaving &lt;code&gt;argv&lt;/code&gt; stripped of all &lt;code&gt;-Xtidy&lt;/code&gt; and the immediately following option. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And it &lt;strong&gt;&lt;em&gt;just did it correctly&lt;/em&gt;&lt;/strong&gt; in several seconds, all without me having to debug the inevitable off-by-one errors had I written the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Experience
&lt;/h2&gt;

&lt;p&gt;If you’re an experienced programmer, you’re able to look at the generated code and quickly tell whether it looks right.  So for an experienced programmer, AI is quite the accelerant; if you’re an inexperienced programmer (or not even a programmer), then I suppose you’re at the mercy of the monkey’s paw.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding Bugs
&lt;/h2&gt;

&lt;p&gt;Another thing you can do, when you’re finished with a particular &lt;code&gt;.c&lt;/code&gt; or &lt;code&gt;.cpp&lt;/code&gt; file, is upload it and ask, “Can you find any bugs in this code?” &lt;strong&gt;&lt;em&gt;And it does&lt;/em&gt;&lt;/strong&gt;.  Of course you can’t tell whether it found &lt;em&gt;all&lt;/em&gt; bugs, so you should still write unit and other tests.&lt;/p&gt;

&lt;p&gt;It can of course report false positives as it did with my &lt;a href="https://github.com/paul-j-lucas/c_chan" rel="noopener noreferrer"&gt;&lt;code&gt;c_chan&lt;/code&gt;&lt;/a&gt; project.  It thought my use of a particular mutex was wrong.  Granted, it was an atypical way to use a mutex that perhaps would have also confused human programmers.  But it also did find a few other real bugs including uninitialized structure members and noticing that the &lt;code&gt;tv_nsec&lt;/code&gt; member of a &lt;a href="https://en.cppreference.com/c/chrono/timespec" rel="noopener noreferrer"&gt;&lt;code&gt;timespec&lt;/code&gt;&lt;/a&gt; structure &lt;em&gt;needs&lt;/em&gt; to be in the range 0–999999999, so I should &lt;a href="https://github.com/paul-j-lucas/c_chan/commit/83fec86fa5c925c1d486b9dce9b4730ab75e900d" rel="noopener noreferrer"&gt;add code to check for overflow&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the AI Did Not Do
&lt;/h2&gt;

&lt;p&gt;Like many codebases, the bulk of the code isn’t directly involved in doing whatever the main point of the codebase is.  In Tidy’s case:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only 18% has to do with scanning for &lt;code&gt;#include&lt;/code&gt; directives and mapping symbols to include files.&lt;/li&gt;
&lt;li&gt;26% is just “utility” code (small functions that make writing the rest of the code easier).&lt;/li&gt;
&lt;li&gt;25% is just for parsing configuration files (syntactically parsing TOML, semantically interpreting it, checking for errors, printing error messages with exact line and column).&lt;/li&gt;
&lt;li&gt;15% for generic data structures (dynamic arrays, red-black trees).&lt;/li&gt;
&lt;li&gt;9% for command-line parsing.&lt;/li&gt;
&lt;li&gt;8% for test.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I used AI to &lt;em&gt;assist&lt;/em&gt; with (not &lt;em&gt;write&lt;/em&gt;) code using Libclang, not for utility code nor configuration files, only a tiny bit with the command-line (to split arguments), and not for test.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implications
&lt;/h2&gt;

&lt;p&gt;While my intent for this blog post is only to describe my impressions of AI for software development for &lt;em&gt;me&lt;/em&gt;, I’m probably going to get asked in the comments what I think the implications are for software development as a whole, so I might as well just address that now.&lt;/p&gt;

&lt;p&gt;While there certainly has been and will continue to be a lot of hype about AI, as I’ve said, it’s helped me a &lt;em&gt;lot&lt;/em&gt; with Tidy.  It’s a game-changer for software development.  In the hands of an experienced programmer, it’s an accelerant.  Since I’m no longer an inexperienced programmer, I can’t directly comment on what AI use is like for inexperienced programmers.  It’s very likely also an accelerant, but inexperienced (or non-) programmers can’t spot wrong or security-omitting code when they see it.  There will be more data breaches and lawsuits for sure.&lt;/p&gt;

&lt;p&gt;You’ve undoubtedly heard (and perhaps unfortunately directly experienced) the rampant layoffs at tech. companies.  As I &lt;a href="https://www.linkedin.com/posts/pauljaylucas_the-case-against-an-imminent-software-developer-share-7456219314787094528-FJrZ" rel="noopener noreferrer"&gt;commented&lt;/a&gt;, yes, there have been lots of layoffs, but I think AI is being used as a scapegoat to make CEOs not sound incompetent and companies not sound in trouble. The reasons for layoffs are the same as ever:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The company stupidly over-hired in general.&lt;/li&gt;
&lt;li&gt;A new product or service didn’t pan out.&lt;/li&gt;
&lt;li&gt;The company is in financial trouble.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of which make the CEO look incompetent. Instead by blaming AI, it makes the CEO look savvy by simultaneously adopting cutting edge technology while also cutting expenses — both of which are rewarded by Wall Street.&lt;/p&gt;

&lt;p&gt;To that, I’d also add the following reason for layoffs. Incompetent CEOs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Might actually believe all the hype and think they &lt;em&gt;can&lt;/em&gt; replace developers by AI.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Consider the following scenario. You’re the CEO of a tech. company that sells a flagship software product with a large customer base. You have 100 developers on staff.  On average, you add one new feature and fix 10 bugs per month. You’d like to add more features and fix more bugs per month, but can’t afford to hire more developers. Now along comes AI and you have two options:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Continue to add one new feature and fix 10 bugs per month, but with fewer developers and expense.&lt;/li&gt;
&lt;li&gt;Add two or even three new features and fix 30 bugs per month with the same number of developers using AI as an accelerant.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What sane CEO chooses option 1 thinking, “We’re happy with our current pace of development as are our customers”? Option 2 makes both existing customers happier and likely will be better at attracting new customers.  Indeed, there has been some &lt;a href="https://www.zdnet.com/article/rumors-of-the-software-developers-ai-induced-demise-are-greatly-exaggerated/" rel="noopener noreferrer"&gt;research&lt;/a&gt; that supports this.&lt;/p&gt;

&lt;p&gt;So if you’ve been affected by a layoff, perhaps you can take some comfort (&lt;a href="https://en.wikipedia.org/wiki/Schadenfreude" rel="noopener noreferrer"&gt;schadenfreude&lt;/a&gt;) in the likelihood that the CEO is incompetent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;AI is very likely here to stay.  It’s clearly a developer accelerant.  Sure, there will be shake-ups, buy-outs, and a few bankruptcies, because, at least currently, running AI hemorrhages money.  Making AI &lt;em&gt;profitable&lt;/em&gt; is another matter.  Big players like Google that have an alternate cash cow (advertising) can fund AI indefinitely; Anthropic is only &lt;a href="https://www.wsj.com/tech/ai/mind-blowing-growth-is-about-to-propel-anthropic-into-its-first-profitable-quarter-7edbf2f4" rel="noopener noreferrer"&gt;just now turning a profit&lt;/a&gt; for the first time ever.  It’s unclear whether they’ll be able to &lt;em&gt;continue&lt;/em&gt; to turn a profit.  The next few years will tell.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>programming</category>
    </item>
    <item>
      <title>Symbolic Constant Conundrum</title>
      <dc:creator>Paul J. Lucas</dc:creator>
      <pubDate>Sat, 23 May 2026 00:34:36 +0000</pubDate>
      <link>https://dev.to/pauljlucas/symbolic-constant-conundrum-40e7</link>
      <guid>https://dev.to/pauljlucas/symbolic-constant-conundrum-40e7</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;A &lt;em&gt;symbolic constant&lt;/em&gt; in any programming language is a name — a &lt;em&gt;symbol&lt;/em&gt; — that can be used to stand in for a &lt;em&gt;constant&lt;/em&gt; — a literal value.  Programming languages inherited symbolic constants from mathematics that has many of them grouped by specific field of study.  Examples include: π (pi), &lt;em&gt;c&lt;/em&gt; (speed of light), e (Euler’s number), G (gravitational constant), &lt;em&gt;h&lt;/em&gt; (Plank’s constant), etc. While those exact constants can be defined and used in programs, many programs define program-specific constants.  Using constants is better than using &lt;a href="https://en.wikipedia.org/wiki/Magic_number_(programming)" rel="noopener noreferrer"&gt;magic numbers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Both C and C++ have acquired multiple ways to specify symbolic constants as their respective languages have evolved over the decades, namely:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Macros (via &lt;code&gt;#define&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Enumerations.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;const&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;constexpr&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Knowing which of the ways to use in a particular case can be quite the conundrum.&lt;/p&gt;

&lt;h2&gt;
  
  
  Macros
&lt;/h2&gt;

&lt;p&gt;Originally, C &lt;em&gt;only&lt;/em&gt; had &lt;a href="https://dev.to/pauljlucas/cc-preprocessor-macros-fh5"&gt;macros&lt;/a&gt;, specifically, object-like macros, e.g.:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#define BUF_SIZE  8192
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Macros are adequate, but not &lt;em&gt;good&lt;/em&gt;.  Why?  Macros in general ignore scope, so you typically have to give macros &lt;em&gt;very&lt;/em&gt; specific (long) names to avoid collision.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enumerations
&lt;/h2&gt;

&lt;p&gt;Enumerations in &lt;a href="https://dev.to/pauljlucas/enumerations-in-c-ae7"&gt;C&lt;/a&gt; and &lt;a href="https://dev.to/pauljlucas/enumerations-in-c-pn9"&gt;C++&lt;/a&gt; are better, especially for declaring a set of &lt;em&gt;related&lt;/em&gt; constants.  In C++ with &lt;code&gt;enum class&lt;/code&gt;, they can even be scoped to avoid collisions; in C, however, they’s still in the global scope.&lt;/p&gt;

&lt;p&gt;The other caveat is that they can be constants only for integral values.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;const&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;As I described for &lt;a href="https://dev.to/pauljlucas/c-const-conundrum-j2l"&gt;C&lt;/a&gt; and &lt;a href="https://dev.to/pauljlucas/const-conundrum-2bfj"&gt;C++&lt;/a&gt;, you can use &lt;code&gt;const&lt;/code&gt; for constants, e.g.:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;BUF_SIZE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8192&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;BUF&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;BUF_SIZE&lt;/span&gt; &lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;local_buf&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;BUF_SIZE&lt;/span&gt; &lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In C++, that will compile just fine without warning; in C, it’ll either be accepted with warnings or rejected entirely, especially if you disable language extensions. Why?  Because &lt;code&gt;const&lt;/code&gt; is a misnomer since it really means &lt;em&gt;immutable&lt;/em&gt;, not &lt;em&gt;constant&lt;/em&gt;, and C is more picky about it.&lt;/p&gt;

&lt;p&gt;While the declaration of &lt;code&gt;BUF&lt;/code&gt; might be accepted, the declaration of &lt;code&gt;local_buf&lt;/code&gt; will either be considered a variable length array (VLA) (that, as I &lt;a href="https://dev.to/pauljlucas/obscure-c99-array-features-3270"&gt;pointed out&lt;/a&gt;, you should probably never use), or rejected since VLAs are an optional feature and not all compilers support them (notably, Microsoft’s C compiler doesn’t).&lt;/p&gt;

&lt;p&gt;A common work-around in C (prior to C23, see below) is to (ab)use &lt;code&gt;enum&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;BUF_SIZE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8192&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is, use a nameless enumeration.  The advantage is that enumeration constants really are &lt;em&gt;constant&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;constexpr&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;If you’re using C++11 or later, or C23 or later, there’s &lt;code&gt;constexpr&lt;/code&gt;.  Unlike &lt;code&gt;const&lt;/code&gt;, &lt;code&gt;constexpr&lt;/code&gt; really means &lt;em&gt;constant&lt;/em&gt;.  This is by far the best option for declaring constants:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;constexpr&lt;/span&gt; &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="n"&gt;BUF_SIZE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8192&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;To summarize:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you’re declaring a set of related, integral constants, use &lt;code&gt;enum&lt;/code&gt; (in C) or &lt;code&gt;enum class&lt;/code&gt; (in C++).&lt;/li&gt;
&lt;li&gt;Otherwise, use &lt;code&gt;constexpr&lt;/code&gt; if you can.&lt;/li&gt;
&lt;li&gt;Otherwise, use &lt;code&gt;const&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Otherwise, use &lt;code&gt;#define&lt;/code&gt; as a last resort.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>c</category>
      <category>cpp</category>
    </item>
    <item>
      <title>include-tidy: A Tool to Enforce Include-What-You-Use</title>
      <dc:creator>Paul J. Lucas</dc:creator>
      <pubDate>Fri, 22 May 2026 01:56:57 +0000</pubDate>
      <link>https://dev.to/pauljlucas/include-tidy-a-tool-to-enforce-include-what-you-use-20mh</link>
      <guid>https://dev.to/pauljlucas/include-tidy-a-tool-to-enforce-include-what-you-use-20mh</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Unlike &lt;a href="https://go.dev/" rel="noopener noreferrer"&gt;Go&lt;/a&gt; where the language definition itself via its compiler strictly enforces the inclusion of modules (i.e., include &lt;em&gt;exactly&lt;/em&gt; what you use, no more, no less), neither the C nor C++ language definitions have an equivalent enforcement.  This can lead to two problems:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;If you unnecessarily include a header that’s not needed (i.e., no symbols from it are referenced), then compilation gets a tiny bit slower.  For small codebases, this is negligible; for larger codebases where build times can take the better part of an hour or even exceed an hour, it matters.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you don’t directly include a header that’s needed (i.e., one or more symbols from it are referenced), then if you remove a seemingly unrelated &lt;code&gt;#include&lt;/code&gt;, the build can break.  Alternatively, your program may build just fine on one platform, but fail on another due to either system headers being slightly different or &lt;code&gt;#ifdef&lt;/code&gt;s.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To avoid both problems, you should follow the &lt;em&gt;include-what-you-use&lt;/em&gt; principle, namely that a source file:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Directly includes every header file exactly once from which it references symbols.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Does not include a header file from which it does not reference symbols.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;While you can attempt to adhere to that principle manually, it can be difficult as the number of headers either in or used by a project increases.&lt;/p&gt;

&lt;p&gt;You’d think there would be a way to automate checking a source file for violations of the principle — and there is.  After just a little bit of searching, I found &lt;a href="https://include-what-you-use.org/" rel="noopener noreferrer"&gt;&lt;code&gt;include-what-you-use&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;include-what-you-use&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Having found &lt;code&gt;include-what-you-use&lt;/code&gt; (iwyu), I tried it out.  It sort-of worked, but gave incorrect suggestions.  For example, when using &lt;code&gt;getopt_long&lt;/code&gt; via &lt;a href="https://www.gnu.org/software/gnulib/" rel="noopener noreferrer"&gt;Gnulib&lt;/a&gt;, it said I needed to include &lt;code&gt;getopt-ext.h&lt;/code&gt;.  While that’s technically correct (because that’s the file in Gnulib that declares &lt;code&gt;getopt_long&lt;/code&gt;), that file is a Gnulib implementation detail that user’s aren’t supposed to know or care about; users are still only supposed to include &lt;code&gt;getopt.h&lt;/code&gt;. Iwyu has a way to fix this via “mapping files,” but it’s annoying that you have to do it manually.&lt;/p&gt;

&lt;p&gt;It seemed to me that if you include a standard(ish) header like &lt;code&gt;getopt.h&lt;/code&gt;, then any headers that &lt;code&gt;getopt.h&lt;/code&gt; includes should be considered implementation details, i.e., &lt;code&gt;getopt.h&lt;/code&gt; should automatically be a &lt;em&gt;proxy&lt;/em&gt; for headers it includes so that any symbols declared in those other headers should be treated &lt;em&gt;as-if&lt;/em&gt; they were declared in &lt;code&gt;getopt.h&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Since the sets of &lt;a href="https://en.cppreference.com/c/header" rel="noopener noreferrer"&gt;C&lt;/a&gt;, &lt;a href="https://en.cppreference.com/cpp/header" rel="noopener noreferrer"&gt;C++&lt;/a&gt;, and &lt;a href="https://pubs.opengroup.org/onlinepubs/9699919799/idx/head.html" rel="noopener noreferrer"&gt;POSIX&lt;/a&gt; standard headers are defined, then any header included by one of the standard headers should automatically be considered an implementation detail and the standard headers should automatically proxy for those other headers.&lt;/p&gt;

&lt;p&gt;Aside from that, I found iwyu less than ideal in a few other ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Some configuration is done via the aforementioned mapping files while other configuration is done via special &lt;code&gt;IWYU&lt;/code&gt; comments in source code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Iwyu has been around since 2011.  As of this writing in 2026, that’s 15 years (!) and it’s &lt;em&gt;still&lt;/em&gt; only at version 0.26.  While it is under active development, it’s apparently progressing &lt;em&gt;very&lt;/em&gt; slowly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Looking at its &lt;a href="https://github.com/include-what-you-use/include-what-you-use" rel="noopener noreferrer"&gt;source code repository&lt;/a&gt; confirms development is progressing slowly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Looking at its &lt;a href="https://github.com/include-what-you-use/include-what-you-use/issues" rel="noopener noreferrer"&gt;open issues&lt;/a&gt;, it’s probably going to be a while since those get fixed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Part of the slowness might be due to iwyu using the &lt;a href="https://llvm.org/docs/ProgrammersManual.html" rel="noopener noreferrer"&gt;C++ LLVM API&lt;/a&gt; that’s not intended to be a stable API.  (It’s intended to support LLVM and &lt;code&gt;clang&lt;/code&gt; themselves.)  Hence, any time the API changes, they authors have to spend time updating iwyu.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When a file has no violations (adheres to the include-what-you-use principle), there’s no way to have iwyu be silent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It uses underscores for its long command-line options that are more annoying to type than dashes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;include-tidy&lt;/code&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;Given the state of iwyu, I decided to write my own tool to enforce the include-what-you-use principle: &lt;a href="https://github.com/paul-j-lucas/include-tidy" rel="noopener noreferrer"&gt;&lt;code&gt;include-tidy&lt;/code&gt;&lt;/a&gt; (Tidy).  I optimistically (naively?) thought “How hard can it be?”  While the core functionality wasn’t hard (I implemented it in a couple of weeks), it’s invariably the corner cases, the last 10%, that takes 90% of the time.  Even so, I’ve gotten Tidy to 1.0 in approximately two months.&lt;/p&gt;

&lt;p&gt;While it’s non-trivial to write a full C parser since C is (still) a relatively small language, is tractable for one person; but it’s simply too much work to write a full C++ parser.  Instead of using the unstable Clang C++ API, I used the stable &lt;a href="https://clang.llvm.org/docs/LibClang.html" rel="noopener noreferrer"&gt;Libclang&lt;/a&gt; C API instead to do all the parsing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use of AI
&lt;/h3&gt;

&lt;p&gt;What helped a &lt;em&gt;lot&lt;/em&gt; was using AI (strictly speaking, an LLM), specifically Google’s &lt;a href="https://gemini.google.com/" rel="noopener noreferrer"&gt;Gemini&lt;/a&gt; (because I’m too cheap to pay for &lt;a href="https://claude.ai/" rel="noopener noreferrer"&gt;Claude&lt;/a&gt;, especially for a personal project that I have no intention of making any money from).  I’ll state briefly that AI saved me from having to read a lot of the documentation, read the tutorials, post questions to a mailing list or &lt;a href="https://stackoverflow.com/" rel="noopener noreferrer"&gt;Stack Overflow&lt;/a&gt;, and wait for answers (if any).  My full impression of AI is a &lt;a href="https://dev.to/pauljlucas/my-impression-of-ai-in-programming-33ci"&gt;story for another time&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;My use of AI does &lt;strong&gt;&lt;em&gt;not&lt;/em&gt;&lt;/strong&gt; mean &lt;code&gt;include-tidy&lt;/code&gt; was written &lt;em&gt;by&lt;/em&gt; AI, certainly not copied verbatim (I don’t like its coding style); but the AI certainly pointed me in the right direction.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuration
&lt;/h3&gt;

&lt;p&gt;Unlike iwyu, I wanted Tidy to be fully configurable via files.  The choices these days are &lt;a href="https://www.json.org/" rel="noopener noreferrer"&gt;JSON&lt;/a&gt;, &lt;a href="https://toml.io/" rel="noopener noreferrer"&gt;TOML&lt;/a&gt;, &lt;a href="https://www.w3.org/TR/xml/" rel="noopener noreferrer"&gt;XML&lt;/a&gt;, and &lt;a href="https://yaml.org/" rel="noopener noreferrer"&gt;YAML&lt;/a&gt;.  IMHO, the least bad of these is TOML.  Given that choice, the next task was to be able to parse TOML files.&lt;/p&gt;

&lt;p&gt;I looked for a TOML library with a C API and found &lt;a href="https://github.com/arp242/toml-c" rel="noopener noreferrer"&gt;a&lt;/a&gt; &lt;a href="https://github.com/cktan/tomlc17" rel="noopener noreferrer"&gt;couple&lt;/a&gt;, but it wasn’t obvious which one was better.  I also didn’t like the idea of having another dependency in addition to Libclang.  So I decided to implement my own TOML libary.  I optimistically (naively?) thought “How hard can it be?” (Sound familiar?)&lt;/p&gt;

&lt;p&gt;Actually, compared to implementing Tidy, implementing a TOML library was much easier.  Part of that was due to me not having to implement a full TOML parser because Tidy simply doesn’t need things like dates, times, floating-point numbers, arrays of or inline tables, multi-line strings, or Unicode.&lt;/p&gt;

&lt;p&gt;Tidy also implements configuration file “layering.”  There can be a default, system-wide configuration file in &lt;code&gt;/etc/xdg/include-tidy/config.toml&lt;/code&gt; (Tidy implements the &lt;a href="https://specifications.freedesktop.org/basedir/latest/" rel="noopener noreferrer"&gt;XDG Base Directory Specification&lt;/a&gt;.), a user-specific configuration file in &lt;code&gt;~/.config/include-tidy/config.toml&lt;/code&gt;, and a project-specific configuration file in the project’s source directory.  “Layering” means that settings given in more local configuration files override the same settings in more system-wide configuration files.&lt;/p&gt;

&lt;h3&gt;
  
  
  Command-Line Parsing
&lt;/h3&gt;

&lt;p&gt;One thing I like about iwyu is that it can be used as a drop-in replacement for either a C or C++ compiler, such as either clang or gcc, in that iwyu accepts all command-line options that the compiler accepts, in particular all &lt;code&gt;-D&lt;/code&gt; (macro define) and &lt;code&gt;-I&lt;/code&gt; (include path) options.  This ensures that the code that iwyu “sees” is exactly the same as the compiler normally sees.&lt;/p&gt;

&lt;p&gt;A problem with that is how do you specify iwyu-specific command-line options to iwyu itself? The solution iwyu used is that all such options are preceded by &lt;code&gt;-Xiwyu&lt;/code&gt;.  I decided to do the same for Tidy except use &lt;code&gt;-Xtidy&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Normally, I’d just use &lt;a href="https://www.gnu.org/software/libc/manual/html_node/Getopt-Long-Options.html" rel="noopener noreferrer"&gt;&lt;code&gt;getopt_long()&lt;/code&gt;&lt;/a&gt; as described &lt;a href="https://dev.to/pauljlucas/good-cli-design-implementation-h64"&gt;here&lt;/a&gt; to parse command-line options; but implementing &lt;code&gt;-Xtidy&lt;/code&gt; requires that the options be split into Tidy-specific options (with every occurrence of &lt;code&gt;-Xtidy&lt;/code&gt; removed) and everything else to be passed as-is to Libclang.&lt;/p&gt;

&lt;h3&gt;
  
  
  Include Paths
&lt;/h3&gt;

&lt;p&gt;Every C or C++ compiler &lt;em&gt;knows&lt;/em&gt; what its default set of include directories are; Libclang needs to be told.  The best thing to do is simply to &lt;em&gt;ask&lt;/em&gt; &lt;code&gt;clang&lt;/code&gt; via:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;clang -E -v -xc - &amp;lt;/dev/null 2&amp;gt;&lt;/span&gt;&amp;amp;1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where &lt;code&gt;-E&lt;/code&gt; means run only the preprocessor state, &lt;code&gt;-v&lt;/code&gt; requests verbose output, &lt;code&gt;-xc&lt;/code&gt; sets the language to C, &lt;code&gt;-&lt;/code&gt; reads from &lt;code&gt;stdin&lt;/code&gt;, in this case from &lt;code&gt;/dev/null&lt;/code&gt;. Among other things, &lt;code&gt;clang&lt;/code&gt; fortuitously prints output like (on macOS):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#include &amp;lt;...&amp;gt; search starts here:
 /usr/local/include
 /opt/local/libexec/llvm-22/lib/clang/22/include
 /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include
End of search list.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;clang&lt;/code&gt; can be called with that exact command via &lt;a href="https://pubs.opengroup.org/onlinepubs/009695399/functions/popen.html" rel="noopener noreferrer"&gt;&lt;code&gt;popen()&lt;/code&gt;&lt;/a&gt; and its output can be parsed looking for the &lt;code&gt;#include &amp;lt;...&amp;gt; search starts here:&lt;/code&gt; and &lt;code&gt;End of search list.&lt;/code&gt;  These directories can then be added as arguments to &lt;code&gt;-isystem&lt;/code&gt; command-line options.&lt;/p&gt;

&lt;h3&gt;
  
  
  More Command-Line Parsing
&lt;/h3&gt;

&lt;p&gt;To complicate matters, the command-line arguments have to be pre-scanned to look for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The last argument to get its filename extension to know what language, and thus which include directories, we need.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An &lt;code&gt;-x&lt;/code&gt; option that specifies the language overriding the filename extension.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A &lt;code&gt;--clang&lt;/code&gt; or &lt;code&gt;-C&lt;/code&gt; option to allow the user to override the path to &lt;code&gt;clang&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All this &lt;em&gt;before&lt;/em&gt; ever calling &lt;code&gt;getopt_long()&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sample &lt;code&gt;include-tidy.toml&lt;/code&gt; Configuration File
&lt;/h3&gt;

&lt;p&gt;Not surprisingly, I now &lt;a href="https://en.wikipedia.org/wiki/Eating_your_own_dog_food" rel="noopener noreferrer"&gt;eat my own dog food&lt;/a&gt; and use &lt;code&gt;include-tidy&lt;/code&gt; to tidy itself and my &lt;a href="https://github.com/paul-j-lucas?tab=repositories" rel="noopener noreferrer"&gt;other projects&lt;/a&gt;.  Here’s &lt;code&gt;include-tidy&lt;/code&gt;’s configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[config.h]&lt;/span&gt;
&lt;span class="py"&gt;ignore-as-argument&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="nn"&gt;[pjl_config.h]&lt;/span&gt;
&lt;span class="py"&gt;first&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;keep&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;proxy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s"&gt;"attribute.h"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"config.h"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;config.h&lt;/code&gt; file is auto-generated by &lt;a href="https://dev.to/pauljlucas/autotools-introduction-p9b"&gt;Autotools&lt;/a&gt;.  Auto-generated files should not be run through Tidy since you’re not responsible for their contents.  That’s what the &lt;code&gt;ignore-as-argument&lt;/code&gt; says and this still allows you to run Tidy easily for each file in &lt;code&gt;*.h&lt;/code&gt; without having to make a special case to exclude it.&lt;/p&gt;

&lt;p&gt;For my projects, I create a &lt;code&gt;pjl_config.h&lt;/code&gt; file that wraps &lt;code&gt;config.h&lt;/code&gt;, adds its own macros, and also include &lt;code&gt;attribute.h&lt;/code&gt;.  This should always be the first file included (hence the &lt;code&gt;first = true&lt;/code&gt;), should always be included because it affects other files included from &lt;a href="https://dev.to/pauljlucas/gnu-autoconf-archive-portability-library-45o2"&gt;Gnulib&lt;/a&gt; (hence the &lt;code&gt;keep = true&lt;/code&gt;), and is a proxy for the other two, i.e., if &lt;code&gt;pjl_config.h&lt;/code&gt; is included, then it’s as if &lt;code&gt;attribute.h&lt;/code&gt; and &lt;code&gt;config.h&lt;/code&gt; were included also.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data Structures
&lt;/h3&gt;

&lt;p&gt;The main data structure is one for an included file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;tidy_sort_rank&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;TIDY_SORT_FIRST&lt;/span&gt;       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// The very first `#include`.&lt;/span&gt;
  &lt;span class="n"&gt;TIDY_SORT_ASSOCIATED&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// After first, but before default.&lt;/span&gt;
  &lt;span class="n"&gt;TIDY_SORT_DEFAULT&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;  &lt;span class="c1"&gt;// Default sort rank.&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt;  &lt;span class="n"&gt;tidy_include&lt;/span&gt;    &lt;span class="n"&gt;tidy_include&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt;    &lt;span class="n"&gt;tidy_sort_rank&lt;/span&gt;  &lt;span class="n"&gt;tidy_sort_rank&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;tidy_include&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;CXFile&lt;/span&gt;         &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;              &lt;span class="c1"&gt;// File included.&lt;/span&gt;
  &lt;span class="n"&gt;CXFileUniqueID&lt;/span&gt; &lt;span class="n"&gt;file_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;           &lt;span class="c1"&gt;// Unique file ID.&lt;/span&gt;
  &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt;    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;abs_path&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;          &lt;span class="c1"&gt;// Absolute path.&lt;/span&gt;
  &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt;    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;rel_path&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;          &lt;span class="c1"&gt;// Relative path.&lt;/span&gt;
  &lt;span class="n"&gt;tidy_include&lt;/span&gt;  &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;includer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;          &lt;span class="c1"&gt;// Include including this.&lt;/span&gt;
  &lt;span class="n"&gt;tidy_include&lt;/span&gt;  &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;proxy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;             &lt;span class="c1"&gt;// Proxy include, if any.&lt;/span&gt;
  &lt;span class="kt"&gt;unsigned&lt;/span&gt;       &lt;span class="n"&gt;depth&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;             &lt;span class="c1"&gt;// Include depth.&lt;/span&gt;
  &lt;span class="n"&gt;array_t&lt;/span&gt;        &lt;span class="n"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;             &lt;span class="c1"&gt;// Line(s) included from.&lt;/span&gt;
  &lt;span class="n"&gt;tidy_sort_rank&lt;/span&gt; &lt;span class="n"&gt;sort_rank&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;         &lt;span class="c1"&gt;// Sorting rank.&lt;/span&gt;
  &lt;span class="n"&gt;bool&lt;/span&gt;           &lt;span class="n"&gt;elide&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;             &lt;span class="c1"&gt;// Elide if necessary?&lt;/span&gt;
  &lt;span class="n"&gt;bool&lt;/span&gt;           &lt;span class="n"&gt;keep&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;              &lt;span class="c1"&gt;// Keep if unnecessary?&lt;/span&gt;
  &lt;span class="n"&gt;bool&lt;/span&gt;           &lt;span class="n"&gt;is_local&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;          &lt;span class="c1"&gt;// Local include file?&lt;/span&gt;
  &lt;span class="n"&gt;bool&lt;/span&gt;           &lt;span class="n"&gt;is_proxy_explicit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Was proxy explicit?&lt;/span&gt;
  &lt;span class="n"&gt;rb_tree_t&lt;/span&gt;      &lt;span class="n"&gt;symbol_set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;        &lt;span class="c1"&gt;// Symbols referenced.&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="n"&gt;rb_tree_t&lt;/span&gt; &lt;span class="n"&gt;tidy_include_set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Anything with a &lt;code&gt;CX&lt;/code&gt; prefix is from Libclang.  &lt;code&gt;CXFile&lt;/code&gt; is just an opaque handle to a file; &lt;code&gt;CXFileUniqueID&lt;/code&gt; is an ID Libclang uses for unique file identification.  I use it as the key for &lt;code&gt;tidy_include_set&lt;/code&gt; (that uses &lt;a href="https://github.com/paul-j-lucas/include-tidy/blob/master/src/red_black.h" rel="noopener noreferrer"&gt;&lt;code&gt;rb_tree&lt;/code&gt;&lt;/a&gt;, an implementation of a &lt;a href="https://en.wikipedia.org/wiki/Red%E2%80%93black_tree" rel="noopener noreferrer"&gt;Red-Black tree&lt;/a&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;lines&lt;/code&gt; is an array of line numbers that the file was included from. If the length &amp;gt; 1, it means the file was erroneously included more than once and Tidy reports this.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Normally when printing all include files (when requested), Tidy follows proper &lt;a href="https://dev.to/pauljlucas/proper-header-file-etiquette-ola"&gt;header file etiquette&lt;/a&gt; and puts all local includes first, non-standard, non-local files (such as from a third-party library) second, and standard includes last; within each group, files are sorted alphabetically.  The &lt;code&gt;tidy_sort_rank&lt;/code&gt; allows files (like &lt;code&gt;pjl_config.h&lt;/code&gt;) to be put first followed by a &lt;code&gt;.c&lt;/code&gt; file’s associated &lt;code&gt;.h&lt;/code&gt; file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;symbol_set&lt;/code&gt; is the set of symbols referenced from that include file.  Tidy will print as many of those as will fit in a comment following the &lt;code&gt;#include&lt;/code&gt; (unless told not to).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The rest of the fields should be relatively self-explanatory.&lt;/p&gt;

&lt;p&gt;The other main data structure is one for a referenced symbol:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;tidy_symbol&lt;/span&gt; &lt;span class="n"&gt;tidy_symbol&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;tidy_symbol&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                 &lt;span class="c1"&gt;// Symbol name.&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;rb_tree_t&lt;/span&gt; &lt;span class="n"&gt;symbol_set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;        &lt;span class="c1"&gt;// Set of symbols.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since the structure has only one member, it could be eliminated; but I kept it for future-proofing in case I ever want or need to add additional members.&lt;/p&gt;

&lt;h3&gt;
  
  
  Algorithm Part 1: Included Files
&lt;/h3&gt;

&lt;p&gt;The first part of the algorithm is to iterate through the &lt;a href="https://en.wikipedia.org/wiki/Abstract_syntax_tree" rel="noopener noreferrer"&gt;abstract syntax tree&lt;/a&gt; (AST) of the &lt;a href="https://en.wikipedia.org/wiki/Translation_unit_(programming)" rel="noopener noreferrer"&gt;translation unit&lt;/a&gt; (TU) looking for &lt;code&gt;#include&lt;/code&gt; directives.  Libclang provides a &lt;code&gt;clang_visitChildren()&lt;/code&gt; function that you pass a visitor function to.&lt;/p&gt;

&lt;p&gt;The visitor function gets the file being included (the “included”), the file including it (the “includer”), creates a new &lt;code&gt;tidy_include&lt;/code&gt; object if the included hasn’t been seen before, an initializes &lt;code&gt;depth&lt;/code&gt; that, if zero, means the file was directly included, and initializes other members.&lt;/p&gt;

&lt;p&gt;If the included file has been seen before, it’s possible that it was indirectly included before, but is directly included now.  If that’s the case, then reset the included’s &lt;code&gt;depth&lt;/code&gt; to zero and includer to &lt;code&gt;NULL&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For this part, there’s one other special case. Consider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;/usr/include/sys/wait.h&amp;gt;
  &amp;lt;/usr/include/sys/signal.h&amp;gt;   // #define SIGSTOP 17
...
&amp;lt;/usr/include/signal.h&amp;gt;
  &amp;lt;/usr/include/sys/signal.h&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is, a standard header (e.g., &lt;code&gt;sys/wait.h&lt;/code&gt;) includes a non-standard header (e.g., &lt;code&gt;sys/signal.h&lt;/code&gt;) so &lt;code&gt;sys/signal.h&lt;/code&gt;’s includer is set to &lt;code&gt;sys/wait.h&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Later, the standard header version of the non-standard header (e.g., &lt;code&gt;signal.h&lt;/code&gt;) is included that also includes the non-standard header (&lt;code&gt;sys/signal.h&lt;/code&gt;), so &lt;code&gt;sys/signal.h&lt;/code&gt;’s includer should be reset to be &lt;code&gt;signal.h&lt;/code&gt; because, later still, &lt;code&gt;sys/signal&lt;/code&gt;’s proxy will then be set to be &lt;code&gt;signal.h&lt;/code&gt;, not &lt;code&gt;sys/wait.h&lt;/code&gt;, so &lt;code&gt;signal.h&lt;/code&gt; will be considered the header that defines &lt;code&gt;SIGSTOP&lt;/code&gt; (which is correct) instead of &lt;code&gt;sys/wait.h&lt;/code&gt; (which is incorrect).&lt;/p&gt;

&lt;h3&gt;
  
  
  Algorithm Part 2: Include File Proxies
&lt;/h3&gt;

&lt;p&gt;A second pass of all &lt;code&gt;#include&lt;/code&gt; directives is needed to initialize implicit proxies.  An include file &lt;em&gt;p&lt;/em&gt; can be a proxy for an included file &lt;em&gt;i&lt;/em&gt; only if:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Both &lt;em&gt;i&lt;/em&gt; and &lt;em&gt;p&lt;/em&gt; are non-local includes, i.e., &lt;code&gt;#include &amp;lt;...&amp;gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;i&lt;/em&gt; is not a standard header.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;i&lt;/em&gt; is not directly included (&lt;code&gt;depth&lt;/code&gt; &amp;gt; zero).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There’s an exception at least when using Gnulib.  Consider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;../lib/stdlib.h&amp;gt;
  &amp;lt;/usr/include/stdlib.h&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is, a local implementation of a standard header (as is done when using Gnulib) eventually does a (non-standard) &lt;code&gt;#include_next&lt;/code&gt; to include the real standard one.  The local header (even though has a standard name) should be a proxy for the real one.&lt;/p&gt;

&lt;h3&gt;
  
  
  Algorithm Part 3: Symbols Referenced
&lt;/h3&gt;

&lt;p&gt;Now that all the include files have been found and proxied, a third pass through the AST is needed, this time looking at every symbol (identifier), figuring out where it’s declared, and checking whether the header file that does so is directly included.  This turned out to be harder than I expected.  A &lt;em&gt;lot&lt;/em&gt; harder.  Part of it is due to my naivete (“How hard can it be?”), part is due to quirks of C, and part is due to limitations and quirks of Libclang.&lt;/p&gt;

&lt;h4&gt;
  
  
  Complete vs. Incomplete Types
&lt;/h4&gt;

&lt;p&gt;Consider the following declarations (borrowed by my &lt;a href="https://github.com/paul-j-lucas/cdecl" rel="noopener noreferrer"&gt;&lt;code&gt;cdecl&lt;/code&gt;&lt;/a&gt; project):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="c1"&gt;// c_type.h&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;c_type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// types.h&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;c_type&lt;/span&gt; &lt;span class="n"&gt;c_type_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// c_ast.h&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;c_ast&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;c_type_t&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// dump.h&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;c_type_dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;c_type_t&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;FILE&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;fout&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Suppose we’re tidying &lt;code&gt;c_ast.h&lt;/code&gt;.  Which header(s) does it need to include?  Clearly, it needs &lt;code&gt;types.h&lt;/code&gt; because it declares the &lt;code&gt;typedef&lt;/code&gt; for &lt;code&gt;c_type_t&lt;/code&gt;.  But &lt;code&gt;c_type.h&lt;/code&gt; is &lt;em&gt;also&lt;/em&gt; needed because the &lt;em&gt;complete&lt;/em&gt; type for the &lt;code&gt;c_type_t&lt;/code&gt; — &lt;code&gt;struct c_type&lt;/code&gt; — is needed for the member declaration.&lt;/p&gt;

&lt;p&gt;In contrast, now suppose we’re tidying &lt;code&gt;dump.h&lt;/code&gt;.  Which header(s) does it need to include?  Only &lt;code&gt;types.h&lt;/code&gt; because &lt;code&gt;c_type_t&lt;/code&gt; is used only as part of a pointer declaration and C allows &lt;em&gt;incomplete&lt;/em&gt; types to be used just fine in such cases.  (C++ is the same, but also allows incomplete types for &lt;a href="https://dev.to/pauljlucas/c-references-3b1b"&gt;reference&lt;/a&gt; declarations.)&lt;/p&gt;

&lt;h4&gt;
  
  
  Macros
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://dev.to/pauljlucas/cc-preprocessor-macros-fh5"&gt;Preprocessor macros&lt;/a&gt; add a whole other dimension of complication.  Consider the declaration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="c1"&gt;// util.h&lt;/span&gt;
&lt;span class="cp"&gt;#define POINTER_CAST(T,EXPR)    ((T)(uintptr_t)(EXPR))
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because the macro references &lt;code&gt;uintptr_t&lt;/code&gt;, &lt;code&gt;util.h&lt;/code&gt; should include &lt;code&gt;stdint.h&lt;/code&gt; so the user of the macro can treat it like a black box.&lt;/p&gt;

&lt;p&gt;In Libclang, macro definitions don’t form part of the AST.  Instead, when a definition is encountered, you have to get all the tokens comprising it and iterate over them.  But first you have to parse function-like macros’ parameters, create a set of them, and &lt;em&gt;exclude&lt;/em&gt; them from the tokens while iterating.  You also have to exclude &lt;code&gt;__VA_ARGS__&lt;/code&gt; and &lt;code&gt;__VA_OPT__&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  The Preprocessor’s &lt;code&gt;##&lt;/code&gt; Operator
&lt;/h4&gt;

&lt;p&gt;Another limitation of Libclang is that symbols formed via the preprocessor’s &lt;code&gt;##&lt;/code&gt; (paste) operator aren’t “seen” by Libclang.  Consequently, if such a symbol is declared in a header is referenced and no other symbols from that header are referenced, Tidy won't think the header is necessary.  For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;readline/readline.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="cp"&gt;#define RL_PROMPT_IGNORE(SBUF, WHEN) \
   strbuf_putc( (SBUF), RL_PROMPT_ ## WHEN ## _IGNORE )
&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;prompt_create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;strbuf_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;sbuf&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;RL_PROMPT_IGNORE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;sbuf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;START&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The expansion of &lt;code&gt;RL_PROMPT_IGNORE&lt;/code&gt; will create &lt;code&gt;RL_PROMPT_START_IGNORE&lt;/code&gt; that’s declared in &lt;code&gt;readline.h&lt;/code&gt;.  If no other symbols from it are referenced, Tidy will incorrectly think the header is unnecessary.&lt;/p&gt;

&lt;p&gt;As an alternative to not using &lt;code&gt;##&lt;/code&gt; here, you can add dummy code seen only by Tidy (and Libclang):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#ifdef __include_tidy__
&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;explicitly_reference_symbols&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;RL_PROMPT_START_IGNORE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="cp"&gt;#endif
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is, Tidy implicitly defines &lt;code&gt;__include_tidy__&lt;/code&gt; when tidying.  By explicitly referencing such a symbol directly via dummy code, Libclang will “see” it and Tidy will correctly think the header is necessary.  Because such code is never compiled, the code can be anything (but it still has to be legal and should not generate warnings).&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Tidy was an interesting (and sometimes frustrating) project to work on.  I’m sure there are still bugs, likely more-so with C++ code since most of my testing was with C code.&lt;/p&gt;

</description>
      <category>c</category>
      <category>cpp</category>
    </item>
    <item>
      <title>A Fix for Time Machine Always Making Full Backups</title>
      <dc:creator>Paul J. Lucas</dc:creator>
      <pubDate>Mon, 23 Feb 2026 13:50:14 +0000</pubDate>
      <link>https://dev.to/pauljlucas/a-fix-for-time-machine-always-making-full-backups-44cj</link>
      <guid>https://dev.to/pauljlucas/a-fix-for-time-machine-always-making-full-backups-44cj</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;At some point, I upgraded the macOS version on my iMac from &lt;a href="https://en.wikipedia.org/wiki/MacOS_Sequoia" rel="noopener noreferrer"&gt;Sequoia&lt;/a&gt; to &lt;a href="https://en.wikipedia.org/wiki/MacOS_Tahoe" rel="noopener noreferrer"&gt;Tahoe&lt;/a&gt;.  I think this was the trigger that starting making &lt;a href="https://en.wikipedia.org/wiki/Time_Machine_(macOS)" rel="noopener noreferrer"&gt;Time Machine&lt;/a&gt; always perform full backups to my Mac Mini server.  (Normally, it’s supposed to perform incremental backups.)  Not only was this a &lt;em&gt;lot&lt;/em&gt; slower, but it filled up my back-up disk and caused “disk full” errors. I Google’d, I asked LLMs, tried several things — nothing fixed it. I had to disable Time Machine backups until I found a solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fix
&lt;/h2&gt;

&lt;p&gt;I eventually stumbled across &lt;a href="https://apple.stackexchange.com/a/476007/30226" rel="noopener noreferrer"&gt;this answer&lt;/a&gt;. I’ve distilled the fix into a script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#! /usr/bin/env bash&lt;/span&gt;

&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="c"&gt;# stop on error&lt;/span&gt;

&lt;span class="nv"&gt;ATTRIBUTES&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;
  com.apple.backupd.BackupMachineAddress
  com.apple.backupd.ComputerName
  com.apple.backupd.HostUUID
  com.apple.backupd.ModelID
  com.apple.timemachine.private.structure.metadata
&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="nv"&gt;DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/System/Volumes/Data

&lt;span class="k"&gt;for &lt;/span&gt;attr &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ATTRIBUTES&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;do &lt;/span&gt;xattr &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nv"&gt;$attr&lt;/span&gt; &lt;span class="nv"&gt;$DIR&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, I figured I might as well try it.  So I:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Removed the remote disk as a backup destination.&lt;/li&gt;
&lt;li&gt;Deleted the old backup.&lt;/li&gt;
&lt;li&gt;Ran the script locally on the iMac.&lt;/li&gt;
&lt;li&gt;Re-added the remote disk as a backup destination.&lt;/li&gt;
&lt;li&gt;Kicked off a new backup.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It took several hours to do the first full backup, but after that, it started doing only incremental backups again. Huzzah!&lt;/p&gt;

&lt;p&gt;The reason for this article is to help spread this fix around the Internet to make it easier to stumble across for someone else having the same issue.&lt;/p&gt;

&lt;p&gt;Note that neither I nor very likely the original author of the fix can say that this fix will fix &lt;em&gt;all&lt;/em&gt; situations that might cause Time Machine always to do full backups.&lt;/p&gt;

</description>
      <category>mac</category>
      <category>macos</category>
      <category>timemachine</category>
    </item>
    <item>
      <title>Musings on Structure Declarations</title>
      <dc:creator>Paul J. Lucas</dc:creator>
      <pubDate>Sat, 21 Feb 2026 15:34:59 +0000</pubDate>
      <link>https://dev.to/pauljlucas/musings-on-structure-declarations-cfb</link>
      <guid>https://dev.to/pauljlucas/musings-on-structure-declarations-cfb</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This article is sort-of a follow-up to my &lt;a href="https://dev.to/pauljlucas/musings-on-c-c-declarations-169o"&gt;Musings on C &amp;amp; C++ Declarations&lt;/a&gt; and &lt;a href="https://dev.to/pauljlucas/why-c-requires-the-struct-keyword-for-structures-nec"&gt;Why C Requires the “struct” Keyword for Structures&lt;/a&gt; articles specifically focusing on structure (&lt;code&gt;struct&lt;/code&gt;) declarations.  As a preview, all of the following are valid uses of &lt;code&gt;struct&lt;/code&gt; (independently, but not necessarily consecutively in the same program):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                                &lt;span class="c1"&gt;// 1&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;                  &lt;span class="c1"&gt;// 2a&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                &lt;span class="c1"&gt;// 2b&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                      &lt;span class="c1"&gt;// 3&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;          &lt;span class="c1"&gt;// 4&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c1"&gt;// 5a&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;point_s&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// 5b&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;point_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// 5c&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  1. Forward Structure Declaration
&lt;/h2&gt;

&lt;p&gt;A declaration like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Forward declaration.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is a &lt;em&gt;forward declaration&lt;/em&gt; that effectively tells the compiler “&lt;code&gt;point&lt;/code&gt; is a structure” but without any other details.  What use is that?  It allows you to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create an &lt;em&gt;opaque type&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Break bidirectional type dependencies.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;An opaque type can be used as part of an API for a library where you want to keep the details of a structure hidden from the user.  This has two benefits:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It prevents the user from messing around with the members of the structure when they shouldn’t.&lt;/li&gt;
&lt;li&gt;It makes upgrading a library much simpler.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Consequently, users are forced to use only your API to create, manipulate, and destroy objects of such a type.  It allows you as the library maintainer to add, remove, or change its members at will without fear of breaking users’ programs.  It also allows users to upgrade the version of your library that they use as a drop-in replacement of the shared object file (&lt;code&gt;.so&lt;/code&gt;) without having to recompile their programs.  This is often very useful in live, production systems.&lt;/p&gt;

&lt;p&gt;However, opaque types aren’t without caveats:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;All objects must be dynamically allocated.  This is both slower and more taxing on the memory allocator, especially for many small objects. (However, you might be able to use an &lt;a href="https://dev.to/pauljlucas/using-arenas-for-easier-object-management-145k"&gt;arena&lt;/a&gt;.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No functions operating on an object of the type can be &lt;a href="https://dev.to/pauljlucas/inline-functions-in-c-and-c-2040"&gt;&lt;code&gt;inline&lt;/code&gt;&lt;/a&gt; that may yield worse performance.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A forward declaration can also be used to break interdependencies.  For example, in &lt;a href="https://github.com/paul-j-lucas/cdecl" rel="noopener noreferrer"&gt;cdecl&lt;/a&gt;, an &lt;a href="https://en.wikipedia.org/wiki/Abstract_syntax_tree" rel="noopener noreferrer"&gt;AST&lt;/a&gt; node for a declaration can have an optional alignment; that alignment can be given by a another AST node:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;c_alignas&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="k"&gt;union&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;c_ast&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;type_ast&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Forward declaration.&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;c_ast&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;c_alignas&lt;/span&gt; &lt;span class="n"&gt;align&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;          &lt;span class="c1"&gt;// Alignment, if any.&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unlike C++, a stand-alone forward declaration for a structure isn’t actually needed most of the time since the mere act of &lt;em&gt;mentioning&lt;/em&gt; a &lt;code&gt;struct&lt;/code&gt; type implicitly creates a forward declaration for it.  Above, inside &lt;code&gt;c_alignas&lt;/code&gt;, the &lt;code&gt;struct&lt;/code&gt; declaration simultaneously:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Forward-declares &lt;code&gt;c_ast&lt;/code&gt; as a structure; &lt;em&gt;and&lt;/em&gt;:&lt;/li&gt;
&lt;li&gt;Also declares &lt;code&gt;type_ast&lt;/code&gt; to be a pointer to such a structure.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  2. Ordinary Structure Declaration
&lt;/h2&gt;

&lt;p&gt;A declaration like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is just an ordinary structure declaration; a declaration like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;           &lt;span class="c1"&gt;// Simultaneously declare 'p' as point.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;simultaneously:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Declares an ordinary structure; &lt;em&gt;and&lt;/em&gt;:&lt;/li&gt;
&lt;li&gt;A variable of that structure.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Personally, I don’t like doing this since it’s easy to miss the declaration of the variable way down at the bottom.  For readability, I’d rather be a bit redundant by using separate declarations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Separate declaration is clearer.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Unnamed Structure Declaration
&lt;/h2&gt;

&lt;p&gt;Perhaps curiously, &lt;code&gt;struct&lt;/code&gt; can be used &lt;em&gt;without&lt;/em&gt; a tag name:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That declares an &lt;em&gt;unnamed structure&lt;/em&gt; that’s effectively a one-off.  Note that an unnamed structure is &lt;em&gt;not&lt;/em&gt; the same as an &lt;a href="https://dev.to/pauljlucas/anonymous-structures-in-c-2ebk"&gt;anonymous structure&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Although unnamed structures by themselves are allowed by the grammar, the only use I can think of for them is &lt;a href="https://dev.to/pauljlucas/declaring-multiple-variables-in-a-for-loop-initialization-clause-20n3"&gt;declaring multiple variables in a &lt;code&gt;for&lt;/code&gt; loop initialization clause&lt;/a&gt;.  Additionally, two identical unnamed structures are considered different types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;q&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                   &lt;span class="c1"&gt;// Error: different types.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. &lt;code&gt;typedef&lt;/code&gt; Unnamed Structure Declaration
&lt;/h2&gt;

&lt;p&gt;The only place an unnamed structure is useful is when it’s in combination with a &lt;code&gt;typedef&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Such declarations are common in C code because they bypass the odd tags namespace and directly make structures be first class citizen types.&lt;/p&gt;

&lt;p&gt;Personally, I don’t like doing this since it hides the name of the structure way down at the bottom just like the variable in #2 above.  As above, I’d rather be a bit redundant by using separate declarations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;slist&lt;/span&gt; &lt;span class="n"&gt;slist&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;slist&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;slist&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt;  &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You &lt;em&gt;can&lt;/em&gt; put the &lt;code&gt;typedef&lt;/code&gt; first since, as stated in #1 above, the mere act of &lt;em&gt;mentioning&lt;/em&gt; a &lt;code&gt;struct&lt;/code&gt; type implicitly creates a forward declaration for it.&lt;/p&gt;

&lt;p&gt;The advantage of putting the &lt;code&gt;typedef&lt;/code&gt; first is that you can then use it in the definition of the structure itself as is common in self-referential structures like the singly linked list shown above.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. &lt;code&gt;typedef&lt;/code&gt; Structure Declaration
&lt;/h2&gt;

&lt;p&gt;The last three declarations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c1"&gt;// 5a&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;point_s&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// 5b&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;point_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// 5c&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;combine &lt;code&gt;typedef&lt;/code&gt; with that of a named structure into the same declaration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Case (a) just uses the same name for the tag as the type.&lt;/li&gt;
&lt;li&gt;Case (b) appends &lt;code&gt;_s&lt;/code&gt; to the tag (“s” for &lt;code&gt;struct&lt;/code&gt;).  (I’ve seen some codebases do this.)&lt;/li&gt;
&lt;li&gt;Case (c) appends &lt;code&gt;_t&lt;/code&gt; to the type.  (I’ve seen other codebases do this — even though you really shouldn’t since the &lt;code&gt;_t&lt;/code&gt; suffix is reserved for use by &lt;a href="https://en.wikipedia.org/wiki/POSIX" rel="noopener noreferrer"&gt;POSIX&lt;/a&gt;.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Consistent with case #4 above, I personally don’t like doing any of these either for the same reason.  Again, I’d prefer separate declarations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unions &amp;amp; Enumerations
&lt;/h2&gt;

&lt;p&gt;Everything written above also applies to both &lt;a href="https://dev.to/pauljlucas/unions-in-c-1ojj"&gt;unions&lt;/a&gt; and &lt;a href="https://dev.to/pauljlucas/enumerations-in-c-ae7"&gt;enumerations&lt;/a&gt; with the exception that enumerations can’t be forward declared (until &lt;a href="https://en.wikipedia.org/wiki/C23_(C_standard_revision)" rel="noopener noreferrer"&gt;C23&lt;/a&gt; and with fixed-type enumerations).&lt;/p&gt;

&lt;h2&gt;
  
  
  C++
&lt;/h2&gt;

&lt;p&gt;As mentioned &lt;a href="https://dev.to/pauljlucas/why-c-requires-the-struct-keyword-for-structures-nec"&gt;previously&lt;/a&gt;, C++ effectively does an implicit &lt;code&gt;typedef&lt;/code&gt; for every structure declaration.  To keep compatibility, C++ allows all the ways in which a structure can be declared and referred to in C also:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;point&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="n"&gt;p1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;         &lt;span class="c1"&gt;// Ordinary C++ declaration.&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;point&lt;/span&gt; &lt;span class="n"&gt;p2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// C declaration for compatibility.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Due to the quirky tags namespace, there are several ways to declare structures that has led to inconsistencies across codebases.  For your own code, pick one style and use it consistently.&lt;/p&gt;

</description>
      <category>c</category>
      <category>cpp</category>
    </item>
    <item>
      <title>Why C Requires the “struct” Keyword for Structures</title>
      <dc:creator>Paul J. Lucas</dc:creator>
      <pubDate>Fri, 20 Feb 2026 02:16:00 +0000</pubDate>
      <link>https://dev.to/pauljlucas/why-c-requires-the-struct-keyword-for-structures-nec</link>
      <guid>https://dev.to/pauljlucas/why-c-requires-the-struct-keyword-for-structures-nec</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Regardless of whether you’ve been programming in C for many years or have only recently started, you might wonder why structure declarations require that the &lt;code&gt;struct&lt;/code&gt; keyword be included.  For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="n"&gt;p1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;         &lt;span class="c1"&gt;// Error: "struct" required.&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="n"&gt;p2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// OK.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Obviously, &lt;code&gt;struct&lt;/code&gt; is needed to &lt;em&gt;declare&lt;/em&gt; a structure, but that’s not what this article is about.  This article is about why, once declared, &lt;code&gt;struct&lt;/code&gt; is &lt;em&gt;still&lt;/em&gt; needed to &lt;em&gt;use&lt;/em&gt; the previously declared structure type.  If you omit &lt;code&gt;struct&lt;/code&gt;, the compiler still knows what you &lt;em&gt;mean&lt;/em&gt;, but it pedantically requires that you include the &lt;code&gt;struct&lt;/code&gt; keyword anyway.&lt;/p&gt;

&lt;p&gt;If you’ve programmed in other languages, this requirement seems even more curious because no other language that allows you to declare “structure” (Go), “record” (Pascal), or “class” (C++, Java, Python, and many others) types requires repeating a keyword when you &lt;em&gt;use&lt;/em&gt; the type.  In other languages, such a type becomes a “first class citizen” that can be used just the same as a built-in type like &lt;code&gt;int&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Indeed, when &lt;a href="https://www.stroustrup.com" rel="noopener noreferrer"&gt;Stroustrup&lt;/a&gt; designed C++, he made it so that structure (and class) names are useable as-is without needing to be prefixed by a keyword.  He gave his rationale in &lt;a href="https://www.stroustrup.com/arm.html" rel="noopener noreferrer"&gt;The Annotated C++ Reference Manual&lt;/a&gt; (§3.1c, p.26) an excerpt of which is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Requiring that such prefixing always appear would compromise the effort to make use of user defined types, such as &lt;code&gt;complex&lt;/code&gt;, as similar as possible to use of built-in types, such as &lt;code&gt;int&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Formally, structure, union, and enumeration names are in a separate “tags” namespace.  (I’ll get to unions and enumerations later, but let’s stick to structures for now.)  This means you can have both a structure name and some other identifier name (variable or function) with the same name.  For example, &lt;a href="https://pubs.opengroup.org/onlinepubs/9799919799/" rel="noopener noreferrer"&gt;POSIX&lt;/a&gt; defines &lt;code&gt;stat&lt;/code&gt; as both a &lt;a href="https://pubs.opengroup.org/onlinepubs/009696799/basedefs/sys/stat.h.html" rel="noopener noreferrer"&gt;structure&lt;/a&gt; and a &lt;a href="https://pubs.opengroup.org/onlinepubs/009696799/functions/stat.html" rel="noopener noreferrer"&gt;function&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;stat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;stat&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One not-very-helpful reason why the compiler requires &lt;code&gt;struct&lt;/code&gt; is because that’s how &lt;a href="https://en.wikipedia.org/wiki/Dennis_Ritchie" rel="noopener noreferrer"&gt;Ritchie&lt;/a&gt; designed C.  But then the question becomes, “Why did Ritchie design C that way?”&lt;/p&gt;

&lt;p&gt;So as not to keep you in suspense, as far as I’ve been able to tell, nobody definitively knows the answer.  Sadly, we lost Ritchie in 2011, so nobody can ask him.  However, some people have offered plausible explanations for why &lt;code&gt;struct&lt;/code&gt; is the way it is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Origin Story
&lt;/h2&gt;

&lt;p&gt;Where did the &lt;code&gt;struct&lt;/code&gt; keyword come from?  It’s most likely from &lt;a href="https://en.wikipedia.org/wiki/ALGOL_68" rel="noopener noreferrer"&gt;Algol 68&lt;/a&gt; that has both &lt;strong&gt;&lt;code&gt;STRUCT&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;UNION&lt;/code&gt;&lt;/strong&gt; as keywords.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note that the Algol family of languages uses &lt;a href="https://en.wikipedia.org/wiki/Stropping_(syntax)" rel="noopener noreferrer"&gt;stropping&lt;/a&gt; for keywords, so bold, or some other mechanism, is &lt;em&gt;required&lt;/em&gt; to represent keywords.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But even in Algol 68, there’s no tags namespace.  That idea seems unique to C.&lt;/p&gt;

&lt;h2&gt;
  
  
  C Archeology
&lt;/h2&gt;

&lt;p&gt;If you do some digging, you might come across Ritchie’s &lt;a href="https://www.nokia.com/bell-labs/about/dennis-m-ritchie/cman.pdf" rel="noopener noreferrer"&gt;C Reference Manual&lt;/a&gt; (CRM) published in 1974 that predates &lt;a href="https://en.wikipedia.org/wiki/The_C_Programming_Language" rel="noopener noreferrer"&gt;The C Programming Language&lt;/a&gt; (TCPL1) first published in 1978 by four years.  In CRM §8.2 &lt;em&gt;Type specifiers&lt;/em&gt;, it says:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type-specifier:
        int
        char
        float
        double
        struct { type-decl-list }
        struct identifier { type-decl-list }
        struct identifier
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two things to note:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;If you scan the entire CRM, nowhere is &lt;code&gt;typedef&lt;/code&gt; mentioned. That’s because early versions of C didn’t have &lt;code&gt;typedef&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This means that &lt;em&gt;all&lt;/em&gt; types start with a keyword that would make writing any compiler simpler.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The lack of &lt;code&gt;typedef&lt;/code&gt; can be independently verified by scanning the &lt;a href="https://github.com/dspinellis/unix-history-repo/tree/Research-V6/usr/source/c" rel="noopener noreferrer"&gt;source code for the C compiler&lt;/a&gt;, specifically its &lt;a href="https://github.com/dspinellis/unix-history-repo/blob/4b87ee08354dc081ad897853173e6f7f4b52c116/usr/source/c/c00.c#L28" rel="noopener noreferrer"&gt;keyword table&lt;/a&gt;, that’s part of &lt;a href="https://en.wikipedia.org/wiki/Version_6_Unix" rel="noopener noreferrer"&gt;Sixth Edition Unix&lt;/a&gt; (Unix V6) released in 1975 — no &lt;code&gt;typedef&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implications
&lt;/h2&gt;

&lt;p&gt;As for making it simpler to write a compiler, consider the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;          &lt;span class="c1"&gt;// What is this?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without &lt;code&gt;typedef&lt;/code&gt;, &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt; &lt;em&gt;must&lt;/em&gt; be variables, so the above is an expression for &lt;code&gt;A&lt;/code&gt; times &lt;code&gt;B&lt;/code&gt;.  However, once you add &lt;code&gt;typedef&lt;/code&gt;, &lt;code&gt;A&lt;/code&gt; &lt;em&gt;could&lt;/em&gt; be a type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// "A" is a synonym for "int"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If it is a type, then the above declares &lt;code&gt;B&lt;/code&gt; to be a pointer to type &lt;code&gt;A&lt;/code&gt;.  Hence, it’s &lt;a href="https://en.wikipedia.org/wiki/Context-sensitive_grammar" rel="noopener noreferrer"&gt;context-sensitive&lt;/a&gt;. This definitely complicates both the parser and the lexer often requiring a &lt;a href="https://en.wikipedia.org/wiki/Lexer_hack" rel="noopener noreferrer"&gt;lexer hack&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Hence, it’s likely that Ritchie required &lt;code&gt;struct&lt;/code&gt; to make writing the compiler simpler.  He may have also believed it made code easier to read for humans.  (Generally, programming languages that are easier to parse are also easier for humans to understand.)&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;typedef&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;By the time TCPL1 is published in 1978, &lt;code&gt;typedef&lt;/code&gt; was added to C. This too can be independently verified by scanning the &lt;a href="https://github.com/dspinellis/unix-history-repo/tree/Research-V7/usr/src/cmd/c" rel="noopener noreferrer"&gt;source code for the C compiler&lt;/a&gt;, specifically its &lt;a href="https://github.com/dspinellis/unix-history-repo/blob/5beb5e90fa2d79c2b5608af7ab5829c182a564b6/usr/src/cmd/c/c00.c#L22" rel="noopener noreferrer"&gt;keyword table&lt;/a&gt;, that’s part of &lt;a href="https://en.wikipedia.org/wiki/Version_7_Unix" rel="noopener noreferrer"&gt;Seventh Edition Unix&lt;/a&gt; (Unix V7) released in 1979 — with &lt;code&gt;typedef&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;typedef&lt;/code&gt; is quite handy, both for hiding implementation details especially for types that vary across platforms and helping to write complicated declarations that C is infamous for.  Consider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;sig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)))(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which is the declaration for the &lt;a href="https://pubs.opengroup.org/onlinepubs/9799919799/functions/signal.html" rel="noopener noreferrer"&gt;POSIX library function&lt;/a&gt;.  According to &lt;a href="https://github.com/paul-j-lucas/cdecl" rel="noopener noreferrer"&gt;cdecl&lt;/a&gt; (line breaks added for readability):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cdecl&amp;gt; explain void (*signal(int sig, void (*func)(int)))(int)
declare signal as function
        ( sig as int,
          func as pointer to function (int) returning void )
    returning pointer to function (int) returning void
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That can become &lt;em&gt;much&lt;/em&gt; simpler by using &lt;code&gt;typedef&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="nf"&gt;void&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;sig_t&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;sig_t&lt;/span&gt; &lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;sig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sig_t&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hence, Ritchie added &lt;code&gt;typedef&lt;/code&gt; despite making the compiler harder to write.&lt;/p&gt;

&lt;p&gt;Once &lt;code&gt;typedef&lt;/code&gt; was added, then Ritchie &lt;em&gt;could&lt;/em&gt; have retroactively altered the way &lt;code&gt;struct&lt;/code&gt; is handled by doing away with the tags namespace and making structure types first class citizens.  But by this time, there was already a lot of C code out there and such a change would have broken many programs.  For better or worse, the way &lt;code&gt;struct&lt;/code&gt; worked was metaphorically carved into stone by now.&lt;/p&gt;

&lt;p&gt;If it’s any consolation, &lt;code&gt;typedef&lt;/code&gt; can be used to &lt;em&gt;make&lt;/em&gt; structure types into first class citizens:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="n"&gt;p3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;         &lt;span class="c1"&gt;// No "struct" needed now.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is, &lt;code&gt;typedef&lt;/code&gt; makes &lt;code&gt;point&lt;/code&gt; in the global namespace be an alias for &lt;code&gt;point&lt;/code&gt; in the tags namespace.  The fact that they have the same name is fine since they’re in different namespaces.  Personally, I do this for my own C code. However, other people have &lt;a href="https://www.kernel.org/doc/html/v4.10/process/coding-style.html#typedefs" rel="noopener noreferrer"&gt;different views&lt;/a&gt; on when &lt;code&gt;typedef&lt;/code&gt; should be used.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unions &amp;amp; Enumerations
&lt;/h2&gt;

&lt;p&gt;If you look back at the &lt;em&gt;type-specifier&lt;/em&gt; from CRM, you might also notice that neither &lt;code&gt;union&lt;/code&gt; nor &lt;code&gt;enum&lt;/code&gt; are there either.  &lt;a href="https://dev.to/pauljlucas/unions-in-c-1ojj"&gt;Unions&lt;/a&gt; became part of C by the time of Unix V7 and TCPL1, but &lt;a href="https://dev.to/pauljlucas/enumerations-in-c-ae7"&gt;enumerations&lt;/a&gt; didn’t become part of C until &lt;a href="https://en.wikipedia.org/wiki/ANSI_C" rel="noopener noreferrer"&gt;C89&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Regardless, both &lt;code&gt;union&lt;/code&gt; and &lt;code&gt;enum&lt;/code&gt; work similarly to &lt;code&gt;struct&lt;/code&gt; in that their names are in the same tags namespace.  Ritchie very likely did this for consistency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;So the most likely answer as to why C requires &lt;code&gt;struct&lt;/code&gt; is that it originally made all types start with a keyword that in turn made writing the early compiler simpler.&lt;/p&gt;

</description>
      <category>c</category>
    </item>
    <item>
      <title>Using Arenas for Easier Object Management</title>
      <dc:creator>Paul J. Lucas</dc:creator>
      <pubDate>Thu, 19 Feb 2026 02:47:54 +0000</pubDate>
      <link>https://dev.to/pauljlucas/using-arenas-for-easier-object-management-145k</link>
      <guid>https://dev.to/pauljlucas/using-arenas-for-easier-object-management-145k</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;When I started updating &lt;a href="https://dev.to/pauljlucas/the-all-new-cdecl-30"&gt;Cdecl&lt;/a&gt;, one of the first things I did was, as I then described, to use an &lt;a href="https://en.wikipedia.org/wiki/Abstract_syntax_tree" rel="noopener noreferrer"&gt;abstract syntax tree&lt;/a&gt; (AST) data structure to represent a declaration.  During construction of the AST, placeholder nodes sometimes need to be created until the final type is able to be determined.  For example, consider the declaration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When parsing, upon encountering the first &lt;code&gt;[&lt;/code&gt;, we know it’s an &lt;em&gt;array 2 of “something” of&lt;/em&gt; &lt;code&gt;int&lt;/code&gt;, but we don’t yet know either what the “something” is or whether it will turn out to be nothing.  It’s not until the second &lt;code&gt;[&lt;/code&gt; that we know it’s an &lt;em&gt;array 2 of array 3 of&lt;/em&gt; &lt;code&gt;int&lt;/code&gt;.  (Had the &lt;code&gt;[3]&lt;/code&gt; not been there, then it would have been just &lt;em&gt;array 2 of&lt;/em&gt; &lt;code&gt;int&lt;/code&gt;.)  Once the final type is known, the placeholder node can be replaced by a new code of the correct type.&lt;/p&gt;

&lt;p&gt;You might think all that needs to be done is to call &lt;code&gt;free&lt;/code&gt; on the placeholder node.  You &lt;em&gt;could&lt;/em&gt;, but then you’d have to ensure that there are no other pointers pointing to it, not only in the tree, but in local variables in stack frames of functions on the call stack lest you get a &lt;a href="https://en.wikipedia.org/wiki/Dangling_pointer" rel="noopener noreferrer"&gt;dangling pointer&lt;/a&gt;.  Simpler, would be to use arenas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Arenas
&lt;/h2&gt;

&lt;p&gt;An &lt;a href="https://en.wikipedia.org/wiki/Region-based_memory_management" rel="noopener noreferrer"&gt;arena&lt;/a&gt; typically is a large chunk of dynamically allocated memory from which actual objects of interest are subsequently allocated from using a custom allocator.  There are many ways to implement arenas depending upon the answers to the following questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Will all objects that will be allocated from it be of the same type (or at least size) or different types (or sizes)?&lt;/li&gt;
&lt;li&gt;Will the maximum number of objects that will be allocated from it be known in advance?&lt;/li&gt;
&lt;li&gt;If not, will the arena need to grow as needed?&lt;/li&gt;
&lt;li&gt;Will individual objects need to be deallocated from the arena?&lt;/li&gt;
&lt;li&gt;Does it need to be thread-safe?  (If your particular program doesn’t use threads, then the answer is “no.”)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;About the only thing all arena implementations have in common is that freeing the arena frees all objects in it — which is one of the main reasons for using an arena in the first place.&lt;/p&gt;

&lt;h2&gt;
  
  
  An Arena for Cdecl
&lt;/h2&gt;

&lt;p&gt;In the case of Cdecl, the answers to the previous questions are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Yes.  (All objects are AST nodes.)&lt;/li&gt;
&lt;li&gt;No.  (Won’t know maximum number of objects.)&lt;/li&gt;
&lt;li&gt;Yes.  (Will need to grow as needed.)&lt;/li&gt;
&lt;li&gt;No.  (Individual objects will not need deallocation.)&lt;/li&gt;
&lt;li&gt;No.  (Does not need to be thread-safe.)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Given those answers, all that’s needed to implement an arena is a simple, singly linked list, something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;slist&lt;/span&gt; &lt;span class="n"&gt;slist&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;slist&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;slist&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt;  &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;slist_push_front&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;slist&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;phead&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;slist&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;slist&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;phead&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;phead&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then to put all AST nodes into the arena:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;c_ast_t&lt;/span&gt; &lt;span class="nf"&gt;c_ast_new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="cm"&gt;/* params */&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;slist&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;parena&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;c_ast_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;ast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ast&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="n"&gt;slist_push_front&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;parena&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ast&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ast&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, to free all AST nodes in one go (which is the whole point):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;slist_cleanup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;slist&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;phead&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;free_fn&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;slist&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;phead&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;next&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;free_fn&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;free_fn&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;phead&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As arenas go, a linked list is pretty simple.  It might even be a stretch to call it an arena at all.  In the case of Cdecl, it’s good enough — don’t over-engineer things.&lt;/p&gt;

&lt;h2&gt;
  
  
  More Complex Arenas
&lt;/h2&gt;

&lt;p&gt;A slightly more complex arena would be one where you build on top of the linked list where each node would be a “block” of objects.  For example, the first block could hold a maximum of, say, 8 objects.  If you run out of space, you can allocate more blocks.  Each can either be the same size or double the previous size up to a maximum size:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;arena&lt;/span&gt; &lt;span class="n"&gt;arena&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;arena&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;slist&lt;/span&gt;  &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;blocks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;size_t&lt;/span&gt;  &lt;span class="n"&gt;block_size_min&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;block_size_max&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;size_t&lt;/span&gt;  &lt;span class="n"&gt;obj_size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;size_t&lt;/span&gt;  &lt;span class="n"&gt;avail&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;arena_init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;arena&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;block_size_min&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;block_size_max&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;obj_size&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arena&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;block_size_min&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;block_size_min&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;block_size_max&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;block_size_max&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;obj_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;obj_size&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A block will store both its size and the memory for objects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;arena_block&lt;/span&gt; &lt;span class="n"&gt;arena_block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;arena_block&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;alignas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;max_align_t&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This uses a &lt;a href="https://dev.to/pauljlucas/obscure-c99-array-features-3270"&gt;flexible array member&lt;/a&gt; for the object storage. Given that, we can implement an allocator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;arena_alloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;arena&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;avail&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;arena_block&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arena_node2block&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;blocks&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;block_size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;block_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;block_size_min&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;block_size_max&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;block_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="n"&gt;block_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;block_size_max&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;block&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arena_block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;block_size&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;obj_size&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;avail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;block_size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;slist_push_front&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;blocks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;blocks&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;avail&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;obj_size&lt;/span&gt; &lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;a-&amp;gt;avail&lt;/code&gt; is 0, it means we have to allocate a new block:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ignoring &lt;code&gt;arena_node2block&lt;/code&gt; for now, if &lt;code&gt;block&lt;/code&gt; is &lt;code&gt;NULL&lt;/code&gt;, there are no blocks, so &lt;code&gt;block_size&lt;/code&gt; will be &lt;code&gt;block_size_min&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Otherwise, if doubling &lt;code&gt;block_size&lt;/code&gt; won’t exceed &lt;code&gt;block_size_max&lt;/code&gt;, then double it.&lt;/li&gt;
&lt;li&gt;Otherwise, use &lt;code&gt;block_size_max&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then allocate memory for a block &lt;em&gt;and&lt;/em&gt; &lt;code&gt;block_size&lt;/code&gt; objects and push &lt;code&gt;data&lt;/code&gt; — not &lt;code&gt;block&lt;/code&gt; — onto the head of the linked list of blocks.  This makes it simpler to calculate the address of any object in a block as it done on the &lt;code&gt;return&lt;/code&gt; line.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;size&lt;/code&gt; is “hidden” in memory &lt;em&gt;before&lt;/em&gt; the object pointed to by &lt;code&gt;slist&lt;/code&gt;’s &lt;code&gt;data&lt;/code&gt;.  This trick is commonly used in allocators.  Indeed, it’s typically how &lt;code&gt;malloc&lt;/code&gt; stores the size of a chunk of memory so that it later can be recovered.&lt;/p&gt;

&lt;p&gt;But, given an &lt;code&gt;slist*&lt;/code&gt; for a block, how can you get at the block’s size?  There is where &lt;code&gt;arena_node2block&lt;/code&gt; comes in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="n"&gt;arena_block&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;arena_node2block&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;slist&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arena_block&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;offsetof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arena_block&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The expression &lt;code&gt;node-&amp;gt;data&lt;/code&gt;, being an array, “decays” into a pointer to its first element.  In memory, &lt;code&gt;size&lt;/code&gt;, as mentioned, is stored &lt;em&gt;before&lt;/em&gt; that.  You might think that it’s just &lt;code&gt;sizeof(size_t)&lt;/code&gt; bytes before &lt;code&gt;node-&amp;gt;data&lt;/code&gt; — and it could be. The problem is that there &lt;em&gt;may&lt;/em&gt; be padding between &lt;code&gt;size&lt;/code&gt; and &lt;code&gt;data&lt;/code&gt;.  To subtract the correct number of bytes that includes the padding (if any), the standard macro &lt;a href="https://en.cppreference.com/w/c/types/offsetof.html" rel="noopener noreferrer"&gt;&lt;code&gt;offsetof&lt;/code&gt;&lt;/a&gt; can be used.  In this case, it will return the offset of &lt;code&gt;data&lt;/code&gt; into the structure that &lt;em&gt;includes&lt;/em&gt; the padding (if any).&lt;/p&gt;

&lt;p&gt;To implement a deallocator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;arena_cleanup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;arena&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;free_fn&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;slist&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;blocks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;next_node&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;next_node&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;arena_block&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arena_node2block&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;free_fn&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;avail&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;free_fn&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;obj_size&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;avail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;next_node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;blocks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code is fairly straightforward.  The only thing to remember is that the first block may not be full and you should call &lt;code&gt;free_fn&lt;/code&gt; only only actual objects.  Hence, we start iterating at &lt;code&gt;a-&amp;gt;avail&lt;/code&gt; rather than &lt;code&gt;0&lt;/code&gt;; then set &lt;code&gt;a-&amp;gt;avail&lt;/code&gt; to &lt;code&gt;0&lt;/code&gt; for the remaining blocks that are all full.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Using arenas for object management can simplify memory management in the special case when an entire collection of objects are all deallocated together.  Arenas can also be more performant since it required fewer calls to &lt;code&gt;malloc&lt;/code&gt; and &lt;code&gt;free&lt;/code&gt;.  There are other possible arena implementations in addition to the two presented here.  Keep arenas in mind for your next project.&lt;/p&gt;

</description>
      <category>c</category>
    </item>
    <item>
      <title>Avoid the Temptation of Bit Fields</title>
      <dc:creator>Paul J. Lucas</dc:creator>
      <pubDate>Tue, 27 Jan 2026 01:43:54 +0000</pubDate>
      <link>https://dev.to/pauljlucas/avoid-the-temptation-of-bit-fields-1cnf</link>
      <guid>https://dev.to/pauljlucas/avoid-the-temptation-of-bit-fields-1cnf</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Every once in a while, I come across somebody else’s blog post who’s apparently recently discovered &lt;a href="https://en.cppreference.com/w/c/language/bit_field.html" rel="noopener noreferrer"&gt;bit fields&lt;/a&gt; and thinks they’re nifty in that they allow you to pack things like Boolean flags into single bits.  One example was along the lines of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="n"&gt;running&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="n"&gt;paused&lt;/span&gt;  &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;   &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is, instead of using three whole bytes (24 bits) to store three Boolean flags, you can use just &lt;em&gt;three bits&lt;/em&gt;!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In reality, the original 24 bits would have been padded up to 32 bits and 3 bits would be padded up to at least 8.  Hence, at best, you would have saved 24 bits.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;While that might seem like a pretty good memory savings, there’s no such thing as a free lunch.  With only a very small number of exceptions, such uses of bit fields are both misguided and actually inefficient.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance
&lt;/h2&gt;

&lt;p&gt;Since a byte is the smallest directly addressable unit on a computer, in order to access an individual bit or set of bits like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;set_running&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;running&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the compiler has to generate code equivalent to what you would have done yourself by hand to set just one bit manually.  For example, the &lt;a href="https://godbolt.org/z/3Pzc5d17E" rel="noopener noreferrer"&gt;armv8 generated code&lt;/a&gt; (annotated with C pseudocode) is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ldrb    w8, [x0]     ; char w8 = *x0;
orr     w8, w8, #0x1 ; w8 |= 1;
strb    w8, [x0]     ; *x0 = w8;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Read the existing value from memory (slow).&lt;/li&gt;
&lt;li&gt;Set the bit.&lt;/li&gt;
&lt;li&gt;Write the updated value to memory (slow).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For a normal &lt;code&gt;unsigned&lt;/code&gt;, you do only step 3.  Hence the generated code for either reading or writing bit fields is &lt;em&gt;always&lt;/em&gt; slower.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other Caveats
&lt;/h2&gt;

&lt;p&gt;In addition to the performance penalty, the following things are either unspecified or implementation defined when it comes to bit fields:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Whether the order of the bits is left-to-right or right-to-left.  For the above example, the bits could be in the order &lt;code&gt;rpe&lt;/code&gt; where &lt;code&gt;r&lt;/code&gt; (for &lt;code&gt;running&lt;/code&gt;) is the most significant bit or &lt;code&gt;epr&lt;/code&gt; where &lt;code&gt;e&lt;/code&gt; (for &lt;code&gt;error&lt;/code&gt;) is.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How the bytes containing the bit fields are aligned.  For the above example, they could be &lt;code&gt;rpeXXXXX&lt;/code&gt; or &lt;code&gt;XXXXXrpe&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Whether a multi-bit bit field can straddle a word boundary.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Whether a plain &lt;code&gt;int&lt;/code&gt; bit field is signed or unsigned.  Ordinarily, &lt;code&gt;int&lt;/code&gt; is always signed.  As the type of a bit field, &lt;code&gt;int&lt;/code&gt; becomes like &lt;code&gt;char&lt;/code&gt; in that it’s implementation defined whether it’s signed or unsigned.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Whether types other than &lt;code&gt;int&lt;/code&gt;, &lt;code&gt;signed int&lt;/code&gt;, &lt;code&gt;unsigned int&lt;/code&gt;, &lt;code&gt;_Bool&lt;/code&gt;, &lt;code&gt;_BitInt(N)&lt;/code&gt;, &lt;code&gt;unsigned _BitInt(N)&lt;/code&gt;, or &lt;code&gt;_Atomic&lt;/code&gt; variants can be used as bit fields.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hence, use of bit fields is extremely &lt;em&gt;not&lt;/em&gt; portable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Appropriate Uses
&lt;/h2&gt;

&lt;p&gt;Given that bit fields are slower and not portable, when is it a good idea to use bit fields?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;If you really, &lt;em&gt;really&lt;/em&gt; need the memory savings.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you want code clarity and the performance is inconsequential.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you need to deal with specific hardware that uses sub-byte fields and you have detailed knowledge of your compiler.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For saving memory, if you have other, non-bit field members in a structure, you can also often save memory by sorting members descending by size to minimize padding.&lt;/p&gt;

&lt;p&gt;For code clarity, admittedly code like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is simpler and thus clearer than something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;ERROR_BIT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So if you really want to trade performance for simplicity and clarity, fine, but fully understand the implications of your choice.&lt;/p&gt;

&lt;p&gt;If you need to deal with specific hardware, you can use bit fields to map structures directly to the hardware, but you &lt;em&gt;must&lt;/em&gt; ensure that the code your compiler generates is actually what you think it is — that is you have to know the details of what your particular implementation defines for its implementation defined behavior.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Unless you have a specific reason to use bit fields, don’t.  Especially don’t just because you think they’re either efficient or nifty.&lt;/p&gt;

</description>
      <category>c</category>
    </item>
    <item>
      <title>C23 Miscellany</title>
      <dc:creator>Paul J. Lucas</dc:creator>
      <pubDate>Sat, 03 Jan 2026 16:00:03 +0000</pubDate>
      <link>https://dev.to/pauljlucas/c23-miscellany-flc</link>
      <guid>https://dev.to/pauljlucas/c23-miscellany-flc</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I’ve written a few articles on individual new features in &lt;a href="https://en.wikipedia.org/wiki/C23_(C_standard_revision)" rel="noopener noreferrer"&gt;C23&lt;/a&gt; covering &lt;a href="https://dev.to/pauljlucas/attributes-in-c23-and-c-5eg"&gt;attributes&lt;/a&gt;, &lt;a href="https://dev.to/pauljlucas/auto-in-c23-ij9"&gt;&lt;code&gt;auto&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://dev.to/pauljlucas/bool-in-c23-4kj4"&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/a&gt;, storage classes for &lt;a href="https://dev.to/pauljlucas/compound-literals-in-c-5d5"&gt;compound literals&lt;/a&gt;, &lt;a href="https://dev.to/pauljlucas/c-const-conundrum-j2l"&gt;&lt;code&gt;constexpr&lt;/code&gt;&lt;/a&gt;, explicit underlying types for &lt;a href="https://dev.to/pauljlucas/enumerations-in-c-ae7"&gt;enumerations&lt;/a&gt;, &lt;a href="https://dev.to/pauljlucas/nullptr-in-c23-1cn6"&gt;&lt;code&gt;nullptr&lt;/code&gt;&lt;/a&gt;, and &lt;a href="https://dev.to/pauljlucas/typeof-in-c23-55p2"&gt;&lt;code&gt;typeof&lt;/code&gt;&lt;/a&gt;.  There are a few miscellaneous new features that aren’t substantial enough to warrant individual articles for each, so this article will cover them together.&lt;/p&gt;

&lt;h2&gt;
  
  
  Aggregate Initialization
&lt;/h2&gt;

&lt;p&gt;You can now initialize aggregates (arrays, structures, and &lt;a href="https://dev.to/pauljlucas/unions-in-c-1ojj"&gt;unions&lt;/a&gt;) with an empty &lt;code&gt;= { }&lt;/code&gt;. Previously at a minimum, you had to include a &lt;code&gt;0&lt;/code&gt; between the &lt;code&gt;{&lt;/code&gt; and &lt;code&gt;}&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Binary Literals
&lt;/h2&gt;

&lt;p&gt;C has had decimal, octal, and hexadecimal integer literals since its creation.  C23 adopted binary literals from &lt;a href="https://en.wikipedia.org/wiki/C%2B%2B14#Binary_literals" rel="noopener noreferrer"&gt;C++14&lt;/a&gt; using either the same &lt;code&gt;0b&lt;/code&gt; or &lt;code&gt;0B&lt;/code&gt; prefix:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;b101010&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// 42 decimal&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;_BitInt&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;A new &lt;em&gt;bit-precise integer&lt;/em&gt; type has been added, &lt;code&gt;_BitInt(&lt;/code&gt;&lt;em&gt;n&lt;/em&gt;&lt;code&gt;)&lt;/code&gt; where &lt;em&gt;n&lt;/em&gt; is a positive constant integer expression.  It may be either signed (the default) or &lt;code&gt;unsigned&lt;/code&gt;.  (If signed, &lt;em&gt;n&lt;/em&gt; includes the sign bit.)  Some examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="n"&gt;_BitInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="n"&gt;rgb24&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;// 24-bit RGB color&lt;/span&gt;
&lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="n"&gt;_BitInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;sha256&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// SHA-256&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The maximum value for &lt;em&gt;n&lt;/em&gt; is implementation defined, but is at least as many as for &lt;code&gt;unsigned long long&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Decimal Floating-Point Types
&lt;/h2&gt;

&lt;p&gt;Although they’ve existed as extensions for a while, the new decimal floating-point types of &lt;code&gt;_Decimal32&lt;/code&gt;, &lt;code&gt;_Decimal64&lt;/code&gt;, and &lt;code&gt;_Decimal128&lt;/code&gt; are now officially supported.&lt;/p&gt;

&lt;p&gt;Decimal-floating types are better for calculations involving money (dollars, euros, pounds, etc.) because they’re not subject to the same rounding errors that the standard-floating types are. The standard-floating types are still better for general floating-point calculations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Declarations After Labels
&lt;/h2&gt;

&lt;p&gt;You can now (finally) put declarations immediately after either &lt;code&gt;goto&lt;/code&gt; or &lt;code&gt;case&lt;/code&gt; labels:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="nl"&gt;error:&lt;/span&gt;             &lt;span class="c1"&gt;// C &amp;lt; C23: error; C23: OK&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Previously, you had to use something like the &lt;code&gt;:;&lt;/code&gt; trick (an empty statement after &lt;code&gt;:&lt;/code&gt;) to be legal.  The C Committee should have made this legal when they allowed intermingled declarations and code in &lt;a href="https://en.wikipedia.org/wiki/C99" rel="noopener noreferrer"&gt;C99&lt;/a&gt;, but better late than never.&lt;/p&gt;

&lt;h2&gt;
  
  
  Digit Separators
&lt;/h2&gt;

&lt;p&gt;C23 also adopted the &lt;code&gt;'&lt;/code&gt; character as a digits separator from C++14 as a readability aid:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;b0010&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="mi"&gt;1010&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;299&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="mi"&gt;792&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="mi"&gt;458&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The overall value is not affected.  You’re free to group the digits however you like.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you’re wondering why &lt;code&gt;,&lt;/code&gt; (comma) wasn’t used, it’s because &lt;code&gt;,&lt;/code&gt; is used to separate function arguments and is also the &lt;em&gt;comma operator&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  K&amp;amp;R-Style Functions
&lt;/h2&gt;

&lt;p&gt;Even though function prototypes were adopted from C++ way back in &lt;a href="https://en.wikipedia.org/wiki/ANSI_C" rel="noopener noreferrer"&gt;C89&lt;/a&gt; (the first ANSI C), C has &lt;em&gt;still&lt;/em&gt; supported “K&amp;amp;R style” function declarations and definitions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;strncpy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// C &amp;lt; C23: unspecified arguments&lt;/span&gt;

&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;strncpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, C23 has dropped support for such declarations and definitions.&lt;/p&gt;

&lt;h2&gt;
  
  
  New Keyword Spellings
&lt;/h2&gt;

&lt;p&gt;In addition to &lt;code&gt;bool&lt;/code&gt; replacing &lt;code&gt;_Bool&lt;/code&gt;, &lt;code&gt;alignas&lt;/code&gt; replaces &lt;code&gt;_Alignas&lt;/code&gt;, &lt;code&gt;alignof&lt;/code&gt; replaces &lt;code&gt;_Alignof&lt;/code&gt;, &lt;code&gt;static_assert&lt;/code&gt; replaces &lt;code&gt;_Static_assert&lt;/code&gt;, and &lt;code&gt;thread_local&lt;/code&gt; replaces &lt;code&gt;_Thread_local&lt;/code&gt;.  (The old spellings are still supported, but deprecated.)&lt;/p&gt;

&lt;h2&gt;
  
  
  New Preprocessor Directives
&lt;/h2&gt;

&lt;p&gt;The preprocessor now includes &lt;code&gt;#elifdef&lt;/code&gt;, &lt;code&gt;#elifndef&lt;/code&gt;, &lt;a href="https://cppreference.com/w/c/preprocessor/embed.html" rel="noopener noreferrer"&gt;&lt;code&gt;#embed&lt;/code&gt;&lt;/a&gt;, and &lt;code&gt;#warning&lt;/code&gt; directives.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unnamed, Unused Parameters
&lt;/h2&gt;

&lt;p&gt;Unlike C++, function definitions in C have historically required unused parameters to still be named.  To eliminate an “unused” warning, you typically cast it to &lt;code&gt;void&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nf"&gt;cdecl_rl_completion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// means: unused&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In C23, you can simply omit the name just like you always could in function declarations.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;__VA_OPT__&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Though it’s been supported as an extension by &lt;code&gt;gcc&lt;/code&gt; and &lt;code&gt;clang&lt;/code&gt; for a while, &lt;a href="https://en.cppreference.com/w/c/preprocessor/replace" rel="noopener noreferrer"&gt;&lt;code&gt;__VA_OPT__&lt;/code&gt;&lt;/a&gt; is finally part of the C standard.&lt;/p&gt;

&lt;h2&gt;
  
  
  Variadic Functions
&lt;/h2&gt;

&lt;p&gt;As I mentioned in a previous article, &lt;a href="https://dev.to/pauljlucas/variadic-functions-in-c-53ml"&gt;variadic functions&lt;/a&gt; no longer insist on at least one required parameter; that is you can do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;      &lt;span class="c1"&gt;// C23: no required parameter&lt;/span&gt;
  &lt;span class="kt"&gt;va_list&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;va_start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// C23: no second argument&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ability was adopted from C++.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Of all the changes to C23, &lt;code&gt;auto&lt;/code&gt; will probably be the most used; but the other changes, while not revolutionary, are nice (and sometimes long overdue).&lt;/p&gt;

</description>
      <category>c</category>
    </item>
    <item>
      <title>bool in C23</title>
      <dc:creator>Paul J. Lucas</dc:creator>
      <pubDate>Fri, 19 Dec 2025 02:33:14 +0000</pubDate>
      <link>https://dev.to/pauljlucas/bool-in-c23-4kj4</link>
      <guid>https://dev.to/pauljlucas/bool-in-c23-4kj4</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Originally, C had no boolean type. Instead, &lt;code&gt;int&lt;/code&gt; was invariably used such that &lt;code&gt;0&lt;/code&gt; was treated as false and any non-zero value was treated as true.  While this certainly worked, using &lt;code&gt;int&lt;/code&gt; as a boolean has problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problems with &lt;code&gt;int&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;One problem with using &lt;code&gt;int&lt;/code&gt; as a boolean is clarity. Consider the function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;strbuf_reserve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;strbut_f&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;sbuf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;res_len&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What does that function return?  A simple boolean value? How many bytes were actually reserved? An error code? You have to read the documentation (if any) or the source code (if not — assuming you even have it) to know what the &lt;code&gt;int&lt;/code&gt; means.  If it returned a boolean instead, it would very likely indicate the success or failure.&lt;/p&gt;

&lt;p&gt;Consequently, many programmers, especially those who learned other languages first that had a boolean type (such as ALGOL, Fortran, or Pascal) often defined their own boolean “type” in C, something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#define bool   int  &lt;/span&gt;&lt;span class="cm"&gt;/* or: typedef int bool; */&lt;/span&gt;&lt;span class="cp"&gt;
#define false  0
#define true   1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or perhaps all-caps versions.  However, that can cause its own problem.  If you use a few C libraries from different authors in your program, each might define its own boolean type slightly differently that can lead to incompatibilities, warnings, or errors (depending on how each is defined).&lt;/p&gt;

&lt;p&gt;Another problem with &lt;code&gt;int&lt;/code&gt; as a boolean is that in structures, it takes up at least four times as much space as needed (assuming 32-bit integers).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Although a true boolean value needs only a single bit, it practically must be &lt;code&gt;sizeof(char)&lt;/code&gt; (which is always 1 byte).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;_Bool&lt;/code&gt; in C99
&lt;/h2&gt;

&lt;p&gt;One of the jobs of a language standard committee is to standardize common industry practice to eliminate variances and incompatibilities.  Eventually, the C Committee added a boolean type to C — sort of.&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://en.wikipedia.org/wiki/C99" rel="noopener noreferrer"&gt;C99&lt;/a&gt;, the C Committee finally (after 27 years) added a boolean type to C: &lt;code&gt;_Bool&lt;/code&gt;.  Why was it spelled like that?  Why not simply &lt;code&gt;bool&lt;/code&gt;?  As I wrote in my book &lt;a href="https://dev.to/pauljlucas/why-learn-c-book-released-41c1"&gt;Why Learn C&lt;/a&gt;, §2.2, p. 29:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To evolve C, the C committee occasionally adds new keywords. The problem is that every new keyword has the potential to break existing programs because some may already use the same identifier. To help minimize this possibility, the committee decided that new keywords would generally start with an underscore followed by a capital letter (e.g., &lt;code&gt;_Bool&lt;/code&gt;, §C.6), at least for a transition period to allow people time to update their programs. Such keywords may look odd, but it’s better than breaking programs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;However, the Committee did &lt;em&gt;not&lt;/em&gt; add &lt;code&gt;_False&lt;/code&gt; and &lt;code&gt;_True&lt;/code&gt; keywords, so you &lt;em&gt;still&lt;/em&gt; had to use &lt;code&gt;0&lt;/code&gt; and non-zero.  But they also added &lt;code&gt;stdbool.h&lt;/code&gt; that did:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#define bool  _Bool
#define false 0
#define true  1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;so you could, at your option, &lt;code&gt;#include&lt;/code&gt; that header and use the conventional names.  This half measure worked well enough and, more importantly, didn’t break existing programs.&lt;/p&gt;

&lt;p&gt;But when &lt;a href="https://en.wikipedia.org/wiki/C11_(C_standard_revision)" rel="noopener noreferrer"&gt;C11&lt;/a&gt; with &lt;a href="https://dev.to/pauljlucas/generic-in-c-i48"&gt;&lt;code&gt;_Generic&lt;/code&gt;&lt;/a&gt; came out, &lt;code&gt;_Bool&lt;/code&gt; didn’t play nice with it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdbool.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;f_bool&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;f_int&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cp"&gt;#define F(X)      \
  _Generic( (X),  \
    bool: f_bool, \
    int : f_int   \
  )( (X) )
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;           &lt;span class="c1"&gt;// calls f_bool&lt;/span&gt;
  &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;       &lt;span class="c1"&gt;// calls f_int&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The call of &lt;code&gt;F&lt;/code&gt; passing &lt;code&gt;false&lt;/code&gt; calls &lt;code&gt;f_int&lt;/code&gt; because &lt;code&gt;false&lt;/code&gt; is only a macro for &lt;code&gt;0&lt;/code&gt; — which is an &lt;code&gt;int&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Another difference between &lt;code&gt;int&lt;/code&gt; and &lt;code&gt;_Bool&lt;/code&gt; is what happens when certain values are cast:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt;   &lt;span class="n"&gt;i1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;       &lt;span class="c1"&gt;// = 0 (truncation)&lt;/span&gt;
&lt;span class="kt"&gt;_Bool&lt;/span&gt; &lt;span class="n"&gt;b1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;_Bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;       &lt;span class="c1"&gt;// = 1 (non-zero -&amp;gt; true)&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;   &lt;span class="n"&gt;i2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;LONG_MAX&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// implementation defined&lt;/span&gt;
&lt;span class="kt"&gt;_Bool&lt;/span&gt; &lt;span class="n"&gt;b2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;_Bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;LONG_MAX&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// = 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unlike &lt;code&gt;int&lt;/code&gt;, the semantics of &lt;code&gt;_Bool&lt;/code&gt; are more intuitive and always well defined, specifically, &lt;em&gt;any&lt;/em&gt; non-zero value always gets implicitly converted to &lt;code&gt;1&lt;/code&gt; (true).&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;bool&lt;/code&gt; in C23
&lt;/h2&gt;

&lt;p&gt;In &lt;a href="https://en.wikipedia.org/wiki/C23_(C_standard_revision)" rel="noopener noreferrer"&gt;C23&lt;/a&gt;, the C Committee (after 51 years) added a complete boolean type to C: &lt;code&gt;bool&lt;/code&gt; (deprecating &lt;code&gt;_Bool&lt;/code&gt;).  Not only that, but &lt;code&gt;false&lt;/code&gt; and &lt;code&gt;true&lt;/code&gt; are finally keywords which means the problem with &lt;code&gt;_Generic&lt;/code&gt; goes away.&lt;/p&gt;

&lt;p&gt;Ideally, the C Committee should have added &lt;code&gt;bool&lt;/code&gt; to C11 alongside &lt;code&gt;_Generic&lt;/code&gt; — but better late than never.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Despite taking over a quarter of a century for &lt;code&gt;_Bool&lt;/code&gt; and over half a century for &lt;code&gt;bool&lt;/code&gt;, C finally has a proper boolean type that is clearer and smaller than &lt;code&gt;int&lt;/code&gt; and is always well defined.&lt;/p&gt;

</description>
      <category>c</category>
    </item>
    <item>
      <title>Advanced C Preprocessor Macros for a Type-Safe Varargs Substitute</title>
      <dc:creator>Paul J. Lucas</dc:creator>
      <pubDate>Tue, 16 Dec 2025 03:16:30 +0000</pubDate>
      <link>https://dev.to/pauljlucas/advanced-c-preprocessor-macros-for-a-type-safe-varargs-substitute-2aog</link>
      <guid>https://dev.to/pauljlucas/advanced-c-preprocessor-macros-for-a-type-safe-varargs-substitute-2aog</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;As you may know, &lt;a href="https://en.cppreference.com/w/c/variadic.html" rel="noopener noreferrer"&gt;variadic functions&lt;/a&gt; in C are those that can take a varying number of arguments, the most well-known of which is &lt;a href="https://en.cppreference.com/w/c/io/fprintf" rel="noopener noreferrer"&gt;&lt;code&gt;printf&lt;/code&gt;&lt;/a&gt; and related functions.  As you may also know, variadic functions have a number of caveats as I &lt;a href="https://dev.to/pauljlucas/variadic-functions-in-c-53ml"&gt;previously explained&lt;/a&gt;.  Can type-safe variadic arguments be implemented in standard C?  Yes!&lt;/p&gt;

&lt;h2&gt;
  
  
  A Type-Safe Variadic Argument
&lt;/h2&gt;

&lt;p&gt;First, we need a type that can store a value for any one of C’s built-in types — a type-safe variadic argument (TSVA):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;tsva_type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;TSVA_BOOL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;TSVA_CHAR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;TSVA_SCHAR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;TSVA_SHORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;TSVA_INT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;TSVA_LONG&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;TSVA_LONG_LONG&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;TSVA_UCHAR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;TSVA_USHORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;TSVA_UINT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;TSVA_ULONG&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;TSVA_ULONG_LONG&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;TSVA_FLOAT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;TSVA_DOUBLE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;TSVA_PTR_CHAR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;TSVA_PTR_CONST_CHAR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;TSVA_PTR_VOID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;TSVA_PTR_CONST_VOID&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;tsva_type&lt;/span&gt; &lt;span class="n"&gt;tsva_type_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;tsva_value&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;union&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;bool&lt;/span&gt;                &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;char&lt;/span&gt;                &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;signed&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt;         &lt;span class="n"&gt;sc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;short&lt;/span&gt;               &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;                 &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;long&lt;/span&gt;                &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt;           &lt;span class="n"&gt;ll&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt;       &lt;span class="n"&gt;uc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;short&lt;/span&gt;      &lt;span class="n"&gt;us&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;        &lt;span class="n"&gt;ui&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt;       &lt;span class="n"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt;  &lt;span class="n"&gt;ull&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;float&lt;/span&gt;               &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;double&lt;/span&gt;              &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;char&lt;/span&gt;               &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt;         &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pcc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt;               &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pv&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt;         &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pcv&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="n"&gt;tsva_type_t&lt;/span&gt;           &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;tsva_value&lt;/span&gt; &lt;span class="n"&gt;tsva_value_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is &lt;code&gt;tsva_value&lt;/code&gt; uses an anonymous &lt;a href="https://dev.to/pauljlucas/unions-in-c-1ojj"&gt;&lt;code&gt;union&lt;/code&gt;&lt;/a&gt; to store an argument’s value and &lt;code&gt;type&lt;/code&gt; to store its type.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For &lt;code&gt;char&lt;/code&gt; and &lt;code&gt;void&lt;/code&gt;, the union has pointers to those types.  Ideally, the union should have &lt;code&gt;T*&lt;/code&gt; and &lt;code&gt;T const*&lt;/code&gt; for &lt;em&gt;all&lt;/em&gt; the built-in types.  They were elided here for for brevity.&lt;/p&gt;

&lt;p&gt;The union omits the &lt;code&gt;long double&lt;/code&gt; type since it might be double the size of &lt;code&gt;double&lt;/code&gt; that would double &lt;code&gt;sizeof(tsva_value_t)&lt;/code&gt; for a type that’s rarely used.&lt;/p&gt;

&lt;p&gt;The union also omits the &lt;a href="https://cppreference.com/w/c/language/arithmetic_types.html#Complex_floating_types" rel="noopener noreferrer"&gt;&lt;code&gt;_Complex&lt;/code&gt;&lt;/a&gt; floating-point types as well as the new &lt;a href="https://en.wikipedia.org/wiki/C23_(C_standard_revision)" rel="noopener noreferrer"&gt;C23&lt;/a&gt; &lt;code&gt;_Decimal32&lt;/code&gt;, &lt;code&gt;_Decimal64&lt;/code&gt;, and &lt;code&gt;_Decimal128&lt;/code&gt; types since those would also increase &lt;code&gt;sizeof(tsva_value_t)&lt;/code&gt; for types that are rarely used.&lt;/p&gt;

&lt;p&gt;That said, &lt;code&gt;sizeof(tsva_value_t)&lt;/code&gt; doesn’t really matter (as we’ll see).  If you need any of the omitted types, feel free to add them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Using Type-Safe Variadic Arguments
&lt;/h2&gt;

&lt;p&gt;An example of using type-safe variadic arguments might be a function that can print its arguments like &lt;code&gt;printf&lt;/code&gt;, but in a type-safe way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;tsva_print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tsva_value_t&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;TSVA_CHAR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s"&gt;"%c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;TSVA_INT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s"&gt;"%d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="c1"&gt;// Other types ...&lt;/span&gt;

      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;TSVA_PTR_CHAR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;TSVA_PTR_CONST_CHAR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;fputs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;pc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stdout&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// switch&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is, type-safe variadic arguments will be passed as an “array” (really, a pointer).  Just as with standard variadic arguments, type-safe variadic arguments leave it to the user to determine how to know how many arguments there are.  In this example, the number of elements, &lt;code&gt;n&lt;/code&gt;, is passed as an argument also.&lt;/p&gt;

&lt;p&gt;But how is such a function called?  Specifically, how are the &lt;code&gt;tsva_value_t&lt;/code&gt; elements created?  We can use some macros:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#define TSVA_INIT(TYPE, FIELD, VALUE) \
  (tsva_value_t){ .type = TSVA_##TYPE, .FIELD = (VALUE) }
&lt;/span&gt;
&lt;span class="cp"&gt;#define TSVA_BOOL(VALUE)            TSVA_INIT( BOOL, b, (VALUE) )
#define TSVA_CHAR(VALUE)            TSVA_INIT( CHAR, c, (VALUE) )
#define TSVA_SCHAR(VALUE)           TSVA_INIT( SCHAR, sc, (VALUE) )
#define TSVA_SHORT(VALUE)           TSVA_INIT( SHORT, s, (VALUE) )
#define TSVA_INT(VALUE)             TSVA_INIT( INT, i, (VALUE) )
#define TSVA_LONG(VALUE)            TSVA_INIT( LONG, l, (VALUE) )
#define TSVA_LONG_LONG(VALUE)       TSVA_INIT( LONG_LONG, ll, (VALUE) )
#define TSVA_UCHAR(VALUE)           TSVA_INIT( UCHAR, uc, (VALUE) )
#define TSVA_USHORT(VALUE)          TSVA_INIT( USHORT, us, (VALUE) )
#define TSVA_UINT(VALUE)            TSVA_INIT( UINT, ui, (VALUE) )
#define TSVA_ULONG(VALUE)           TSVA_INIT( ULONG, ul, (VALUE) )
#define TSVA_ULONG_LONG(VALUE)      TSVA_INIT( ULONG_LONG, ull, (VALUE) )
#define TSVA_FLOAT(VALUE)           TSVA_INIT( float, f, (VALUE) )
#define TSVA_DOUBLE(VALUE)          TSVA_INIT( double, d, (VALUE) )
#define TSVA_PTR_CHAR(VALUE)        TSVA_INIT( PTR_CHAR, pc, (VALUE) )
#define TSVA_PTR_CONST_CHAR(VALUE)  TSVA_INIT( PTR_CONST_CHAR, pcc, (VALUE) )
#define TSVA_PTR_VOID(VALUE)        TSVA_INIT( PTR_VOID, pv, (VALUE) )
#define TSVA_PTR_CONST_VOID(VALUE)  TSVA_INIT( PTR_CONST_VOID, pcv, (VALUE) )
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Given those, we can call &lt;code&gt;tsva_print&lt;/code&gt; like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;tsva_print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tsva_value_t&lt;/span&gt;&lt;span class="p"&gt;[]){&lt;/span&gt;
  &lt;span class="n"&gt;TSVA_PTR_CONST_CHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Answer is: "&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;TSVA_INT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While that works, it’s a bit ugly and verbose.  Let’s see if we can clean that up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Counting Variadic Arguments
&lt;/h2&gt;

&lt;p&gt;One of the things that makes the current code ugly, not to mention error-prone, is having to count (correctly!) the number of arguments and pass that.  Can the number of variadic arguments be counted?  Yes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#define VA_ARGS_COUNT(...) \
  ARG_11(__VA_ARGS__ __VA_OPT__(,) 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
&lt;/span&gt;
&lt;span class="cp"&gt;#define ARG_11(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,...) _11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As first shown in an &lt;a href="https://dev.to/pauljlucas/using-advanced-c-preprocessor-macros-for-a-pre-c23c20-vaopt-substitute-43c1"&gt;earlier article&lt;/a&gt;, the &lt;code&gt;ARG_11&lt;/code&gt; macro always returns its 11th argument.  This time, however, it’s being used to implement &lt;code&gt;VA_ARGS_COUNT&lt;/code&gt;.  Just as before, &lt;code&gt;__VA_ARGS__&lt;/code&gt; will “slide” the correct answer (in this case, the number of arguments) into the 11th argument position.  Given that, we can now do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#define tsva_print(...)                     \
  tsva_print( VA_ARGS_COUNT( __VA_ARGS__ ), \
              (tsva_value_t[]){ __VA_ARGS__ } )
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since we’re defining a macro anyway, might as well have it insert the &lt;code&gt;(tsva_value_t[])&lt;/code&gt; compound literal boilerplate code. Now explicitly specifying the count and the boilerplate can be eliminated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;tsva_print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;TSVA_PTR_CONST_CHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Answer is: "&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;TSVA_INT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s better, but the required use of the &lt;code&gt;TSVA_&lt;/code&gt; macros is still quite verbose.  Can those be eliminated?  As it happens, yes (with a caveat).&lt;/p&gt;

&lt;h2&gt;
  
  
  Deducing the Type of Variadic Arguments
&lt;/h2&gt;

&lt;p&gt;What we need is a way to deduce the type of each argument automatically.  As I described in a &lt;a href="https://dev.to/pauljlucas/generic-in-c-i48"&gt;previous article&lt;/a&gt;, &lt;code&gt;_Generic&lt;/code&gt; can be used.&lt;/p&gt;

&lt;p&gt;However, as noted in that article, each type case for &lt;code&gt;_Generic&lt;/code&gt; &lt;em&gt;must&lt;/em&gt; be valid C.  Here, that means we can’t use the &lt;code&gt;TSVA_&lt;/code&gt; macros because it would attempt to assign a given &lt;code&gt;VALUE&lt;/code&gt; to &lt;em&gt;every&lt;/em&gt; union field that would either cause warnings (e.g., assigning a floating-point value to &lt;code&gt;.i&lt;/code&gt;) or errors (e.g., assuming a pointer value to &lt;code&gt;.f&lt;/code&gt;). Instead, we can use helper functions instead of macros:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="n"&gt;tsva_value_t&lt;/span&gt; &lt;span class="nf"&gt;tsva__Bool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;_Bool&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tsva_value_t&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TSVA_BOOL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="n"&gt;tsva_value_t&lt;/span&gt; &lt;span class="nf"&gt;tsva_char&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tsva_value_t&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TSVA_CHAR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="n"&gt;tsva_value_t&lt;/span&gt; &lt;span class="nf"&gt;tsva_signed_char&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;signed&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tsva_value_t&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TSVA_SCHAR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="n"&gt;tsva_value_t&lt;/span&gt; &lt;span class="nf"&gt;tsva_short&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;short&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tsva_value_t&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TSVA_SHORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="n"&gt;tsva_value_t&lt;/span&gt; &lt;span class="nf"&gt;tsva_int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tsva_value_t&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TSVA_INT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="n"&gt;tsva_value_t&lt;/span&gt; &lt;span class="nf"&gt;tsva_long&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tsva_value_t&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TSVA_LONG&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="n"&gt;tsva_value_t&lt;/span&gt; &lt;span class="nf"&gt;tsva_long_long&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tsva_value_t&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TSVA_LONG_LONG&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ll&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="n"&gt;tsva_value_t&lt;/span&gt; &lt;span class="nf"&gt;tsva_unsigned_char&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tsva_value_t&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TSVA_UCHAR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="n"&gt;tsva_value_t&lt;/span&gt; &lt;span class="nf"&gt;tsva_unsigned_short&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;short&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tsva_value_t&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TSVA_USHORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;us&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="n"&gt;tsva_value_t&lt;/span&gt; &lt;span class="nf"&gt;tsva_unsigned_int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tsva_value_t&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TSVA_UINT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ui&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="n"&gt;tsva_value_t&lt;/span&gt; &lt;span class="nf"&gt;tsva_unsigned_long&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tsva_value_t&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TSVA_ULONG&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ul&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="n"&gt;tsva_value_t&lt;/span&gt; &lt;span class="nf"&gt;tsva_unsigned_long_long&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tsva_value_t&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TSVA_ULONG_LONG&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ull&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="n"&gt;tsva_value_t&lt;/span&gt; &lt;span class="nf"&gt;tsva_float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tsva_value_t&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TSVA_FLOAT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="n"&gt;tsva_value_t&lt;/span&gt; &lt;span class="nf"&gt;tsva_double&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tsva_value_t&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TSVA_DOUBLE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="n"&gt;tsva_value_t&lt;/span&gt; &lt;span class="nf"&gt;tsva_ptr_char&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tsva_value_t&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TSVA_PTR_CHAR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="n"&gt;tsva_value_t&lt;/span&gt; &lt;span class="nf"&gt;tsva_ptr_const_char&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tsva_value_t&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TSVA_PTR_CONST_CHAR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pcc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="n"&gt;tsva_value_t&lt;/span&gt; &lt;span class="nf"&gt;tsva_ptr_void&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tsva_value_t&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TSVA_PTR_VOID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="n"&gt;tsva_value_t&lt;/span&gt; &lt;span class="nf"&gt;tsva_ptr_const_void&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tsva_value_t&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TSVA_PTR_CONST_VOID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pcv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Given that, we can implement &lt;code&gt;TSVA_VALUE&lt;/code&gt; using &lt;code&gt;_Generic&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#define TSVA_VALUE(VALUE)                        \
  _Generic( (VALUE),                             \
    _Bool             : tsva__Bool,              \
    char              : tsva_char,               \
    signed char       : tsva_signed_char,        \
    short             : tsva_short,              \
    int               : tsva_int,                \
    long              : tsva_long,               \
    long long         : tsva_long_long,          \
    unsigned char     : tsva_unsigned_char,      \
    unsigned short    : tsva_unsigned_short,     \
    unsigned int      : tsva_unsigned_int,       \
    unsigned long     : tsva_unsigned_long,      \
    unsigned long long: tsva_unsigned_long_long, \
    float             : tsva_float,              \
    double            : tsva_double,             \
    char*             : tsva_ptr_char,           \
    char const*       : tsva_ptr_const_char,     \
    void*             : tsva_ptr_void,           \
    void const*       : tsva_ptr_const_void      \
  )( (VALUE) )
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, each type case is the same by returning a pointer to a function. Hence, now you could instead do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;tsva_print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;TSVA_VALUE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Answer is: "&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;TSVA_VALUE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and the type of each argument is automatically deduced. That’s better in that only a single macro is used, but it’s still verbose.  Can those macros be eliminated completely?&lt;/p&gt;

&lt;h2&gt;
  
  
  Transforming Variadic Arguments
&lt;/h2&gt;

&lt;p&gt;What’s needed is a way for each argument &lt;em&gt;x&lt;/em&gt;, to wrap it as &lt;code&gt;TSVA_VALUE(&lt;/code&gt;&lt;em&gt;x&lt;/em&gt;&lt;code&gt;)&lt;/code&gt;.  Is there a way to have the preprocessor iterate over variadic arguments?  Not directly, but you can via more macro voodoo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#define APPLY_1(MACRO, ARG)        MACRO(ARG)
#define APPLY_2(MACRO, ARG, ...)   MACRO(ARG), APPLY_1(MACRO, __VA_ARGS__)
#define APPLY_3(MACRO, ARG, ...)   MACRO(ARG), APPLY_2(MACRO, __VA_ARGS__)
#define APPLY_4(MACRO, ARG, ...)   MACRO(ARG), APPLY_3(MACRO, __VA_ARGS__)
#define APPLY_5(MACRO, ARG, ...)   MACRO(ARG), APPLY_4(MACRO, __VA_ARGS__)
#define APPLY_6(MACRO, ARG, ...)   MACRO(ARG), APPLY_5(MACRO, __VA_ARGS__)
#define APPLY_7(MACRO, ARG, ...)   MACRO(ARG), APPLY_6(MACRO, __VA_ARGS__)
#define APPLY_8(MACRO, ARG, ...)   MACRO(ARG), APPLY_7(MACRO, __VA_ARGS__)
#define APPLY_9(MACRO, ARG, ...)   MACRO(ARG), APPLY_8(MACRO, __VA_ARGS__)
#define APPLY_10(MACRO, ARG, ...)  MACRO(ARG), APPLY_9(MACRO, __VA_ARGS__)
&lt;/span&gt;
&lt;span class="cp"&gt;#define APPLY_FOR_EACH(MACRO, ...) \
  NAME2(APPLY_, VA_ARGS_COUNT(__VA_ARGS__))(MACRO, __VA_ARGS__)
&lt;/span&gt;
&lt;span class="cp"&gt;#define NAME2(A,B)                NAME2_HELPER(A,B)
#define NAME2_HELPER(A,B)         A ## B
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is, we can use &lt;code&gt;VA_ARGS_COUNT&lt;/code&gt; to count the number of arguments (say, 4), then construct the corresponding &lt;code&gt;APPLY_&lt;/code&gt; macro (say, &lt;code&gt;APPLY_4&lt;/code&gt;) that recursively calls &lt;code&gt;APPLY_&lt;/code&gt;&lt;em&gt;n&lt;/em&gt; for &lt;em&gt;n&lt;/em&gt; &amp;lt; 4 in turn.  Hence, the &lt;code&gt;APPLY_FOR_EACH&lt;/code&gt; macro applies &lt;code&gt;MACRO&lt;/code&gt; to each variadic argument.  Given that, we can define:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#define tsva_print(...)                      \
  tsva_print( VA_ARGS_COUNT( __VA_ARGS__ ),  \
              (tsva_value_t[]){ APPLY_FOR_EACH(TSVA_VALUE, __VA_ARGS__) } )
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and finally do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;tsva_print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s"&gt;"Answer is: "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and it just works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;As this extended example once again shows, the C preprocessor has its own &lt;em&gt;weird&lt;/em&gt; text processing language inside of C. The highlighted techniques of:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Argument “sliding” as shown in &lt;code&gt;ARG_11&lt;/code&gt;; and:&lt;/li&gt;
&lt;li&gt;Argument counting via &lt;code&gt;VA_ARGS_COUNT&lt;/code&gt;; and:&lt;/li&gt;
&lt;li&gt;Transforming arguments via &lt;code&gt;APPLY_FOR_EACH&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;are often used in advanced macros.  In this case, they can provide type-safe variadic arguments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Caveats
&lt;/h2&gt;

&lt;p&gt;While the version of this code that uses the explicit macros of &lt;code&gt;TSVA_BOOL&lt;/code&gt;, &lt;code&gt;TSVA_CHAR&lt;/code&gt;, etc., has no caveats, the version that uses &lt;code&gt;_Generic&lt;/code&gt; does, specifically:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;char&lt;/code&gt; literals are deduced to &lt;code&gt;int&lt;/code&gt;, not &lt;code&gt;char&lt;/code&gt;; and:&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;_Bool&lt;/code&gt; literals of &lt;code&gt;false&lt;/code&gt; and &lt;code&gt;true&lt;/code&gt; are  also deduced to &lt;code&gt;int&lt;/code&gt;, not &lt;code&gt;_Bool&lt;/code&gt;.  (However, this has been fixed in C23; see below.)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Hence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sc"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;_Bool&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;type_print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;      &lt;span class="c1"&gt;// prints "*"&lt;/span&gt;
&lt;span class="n"&gt;type_print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;      &lt;span class="c1"&gt;// prints "false"&lt;/span&gt;

&lt;span class="n"&gt;type_print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;    &lt;span class="c1"&gt;// prints "42", not "*"&lt;/span&gt;
&lt;span class="n"&gt;type_print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// prints "0", not "false"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This isn’t a problem with &lt;code&gt;_Generic&lt;/code&gt;.  In C, the type of a &lt;code&gt;char&lt;/code&gt; literal is simply defined to be &lt;code&gt;int&lt;/code&gt;, not &lt;code&gt;char&lt;/code&gt;.  Prior to &lt;a href="https://en.wikipedia.org/wiki/C11_(C_standard_revision)" rel="noopener noreferrer"&gt;C11&lt;/a&gt; when &lt;code&gt;_Generic&lt;/code&gt; was added, this never mattered; but now it matters.&lt;/p&gt;

&lt;p&gt;The C++ Committee fixed it in C++ because they wanted the ability to overload functions by &lt;code&gt;char&lt;/code&gt; and you can’t do that consistently if &lt;code&gt;char&lt;/code&gt; variables are of type &lt;code&gt;char&lt;/code&gt; but &lt;code&gt;char&lt;/code&gt; literals are of type &lt;code&gt;int&lt;/code&gt;. The C Committee should have fixed the type of &lt;code&gt;char&lt;/code&gt; literals in C11.&lt;/p&gt;

&lt;p&gt;Now in C23 with both &lt;a href="https://dev.to/pauljlucas/auto-in-c23-ij9"&gt;&lt;code&gt;auto&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://dev.to/pauljlucas/typeof-in-c23-55p2"&gt;&lt;code&gt;typeof&lt;/code&gt;&lt;/a&gt;, the problem is even worse:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sc"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;// deduces int, not char&lt;/span&gt;
&lt;span class="n"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// type is int, not char&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly, when &lt;code&gt;_Bool&lt;/code&gt; was added in &lt;a href="https://en.wikipedia.org/wiki/C99" rel="noopener noreferrer"&gt;C99&lt;/a&gt;, it was a transitional type.  Specifically, &lt;code&gt;false&lt;/code&gt; and &lt;code&gt;true&lt;/code&gt; were &lt;em&gt;not&lt;/em&gt; added as keywords, but only macros as &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;1&lt;/code&gt; (integers), respectively, via &lt;code&gt;stdbool.h&lt;/code&gt;.  At least this has finally been &lt;a href="https://dev.to/pauljlucas/bool-in-c23-4kj4"&gt;fixed in C23&lt;/a&gt; now that &lt;code&gt;false&lt;/code&gt; and &lt;code&gt;true&lt;/code&gt; are proper keyword literals for &lt;code&gt;bool&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>c</category>
    </item>
  </channel>
</rss>
