<?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.us-east-2.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>Program Organization (with Examples in C)</title>
      <dc:creator>Paul J. Lucas</dc:creator>
      <pubDate>Tue, 01 Sep 2026 00:54:38 +0000</pubDate>
      <link>https://dev.to/pauljlucas/program-organization-with-examples-in-c-20o1</link>
      <guid>https://dev.to/pauljlucas/program-organization-with-examples-in-c-20o1</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In my book &lt;a href="https://dev.to/pauljlucas/why-learn-c-book-released-41c1"&gt;Why Learn C&lt;/a&gt;, Chapter 13, &lt;strong&gt;Program Organization&lt;/strong&gt;, I wrote in part:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For all but the most trivial programs, a typical C program is composed of several source (&lt;code&gt;.c&lt;/code&gt;) files and header (&lt;code&gt;.h&lt;/code&gt;) files. Often, &lt;code&gt;.c&lt;/code&gt; and &lt;code&gt;.h&lt;/code&gt; files come in pairs where the &lt;code&gt;.c&lt;/code&gt; implements some functionality and the &lt;code&gt;.h&lt;/code&gt; provides the “public” API for using it. All the functions comprising a program are spread among pairs of files with each pair specializing in some particular aspect of the program. One or more pairs roughly approximates a “module” in other languages.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I also gave an example using the source files of &lt;a href="https://github.com/paul-j-lucas/ad" rel="noopener noreferrer"&gt;&lt;code&gt;ad&lt;/code&gt;&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ad.c     color.h   match.c    options.h     unicode.c  util.h
ad.h     dump.c    match.h    pjl_config.h  unicode.h
color.c  dump_c.c  options.c  reverse.c     util.c
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;For example, &lt;code&gt;color.c&lt;/code&gt; contains the definitions of functions for printing text in color to a terminal and its corresponding &lt;code&gt;color.h&lt;/code&gt; contains their declarations so that other files may &lt;code&gt;#include&lt;/code&gt; it to use those functions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The &lt;code&gt;ad&lt;/code&gt; example was chosen for the book because it’s a fairly small program where, consequently, the source files and their names make sense once you know what the purpose of &lt;code&gt;ad&lt;/code&gt; is.  (If you didn’t click the link, &lt;code&gt;ad&lt;/code&gt; dumps the contents of any file as ASCII.)&lt;/p&gt;

&lt;p&gt;One of the things some newcomers to C (or programming in general using any language) struggle with is how to organize source files.  In this article, I’m going to flesh out the details of program organization using a mid-sized program, &lt;a href="https://dev.to/pauljlucas/include-tidy-a-tool-to-enforce-include-what-you-use-20mh"&gt;&lt;code&gt;include-tidy&lt;/code&gt;&lt;/a&gt; (Tidy), as an example.  As a preview, here are its source files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;array.c        file_ext.c         path_util.c       symbol.h
array.h        file_ext.h         path_util.h       toml_lite.c
bit_util.c     fnv1a.c            path_util_test.c  toml_lite.h
bit_util.h     fnv1a.h            pjl_config.h      toml_test.c
clang_util.c   hash_table.c       print.c           trans_unit.c
clang_util.h   hash_table.h       print.h           trans_unit.h
cli_options.c  hash_table_test.c  proxies.c         type_traits.h
cli_options.h  include-tidy.c     proxies.h         typedef.c
color.c        include-tidy.h     red_black.c       typedef.h
color.h        include.c          red_black.h       unit_test.c
config.h       include.h          red_black_test.c  unit_test.h
config_file.c  ipath.c            strbuf.c          util.c
config_file.h  ipath.h            strbuf.h          util.h
cxx.c          options.c          strbuf_test.c
cxx.h          options.h          symbol.c
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compared to &lt;code&gt;ad&lt;/code&gt;, Tidy is about three times its size.&lt;/p&gt;

&lt;h2&gt;
  
  
  Components
&lt;/h2&gt;

&lt;p&gt;Pretty much any program can be broken down conceptually into components.  Perhaps one of the most important distinctions between types of components is &lt;em&gt;program-specific&lt;/em&gt; vs. &lt;em&gt;generic&lt;/em&gt; (or &lt;em&gt;program-agnostic&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;Anything that’s “program-specific” is specific to the particular purpose of the program; anything that’s “generic” could conceivably be used in any program regardless of its purpose. Generally, it’s a good idea to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Minimize the program-specific components because they’re the hardest parts of a program to write (or for others to read and understand — or for yourself in several month’s time) since they’re novel.&lt;/li&gt;
&lt;li&gt;Maximize the generic components because they’re easier to write and test; and, over time, you’ll build up your own personal library of code that can be reused in other programs with few, if any, changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Many programs have the following components.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Program-specific data structures and algorithms&lt;/strong&gt;.  For Tidy, this includes a data structure to represent a symbol referenced in a program and the header file that declares it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generic data structures and algorithms&lt;/strong&gt;.  For Tidy, this includes &lt;a href="https://dev.to/pauljlucas/a-simple-dynamic-array-for-c-1k24"&gt;dynamic arrays&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Hash_table" rel="noopener noreferrer"&gt;hash tables&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Red%E2%80%93black_tree" rel="noopener noreferrer"&gt;red-black trees&lt;/a&gt;, and strings buffers.  (Such things are necessary in C programs because they don’t exist in C’s standard library.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Program options&lt;/strong&gt;.  These allow the behavior of your program to be changed. For Tidy, this includes things like what style of comments you want (if any), what column you want to align comments at, whether you want colored output, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Command-line parsing&lt;/strong&gt;. For Tidy (or any command-line program), parsing command-line options is one way to set program options.  There’s often, but not always, a 1:1 correspondence between a program option and a command-line option.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configuration file parsing&lt;/strong&gt;.  For Tidy (or many programs), parsing a configuration file is another way to set program options — often those that would be too cumbersome to set from the command-line.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Program-specific utilities&lt;/strong&gt;. These include functions that aren’t totally generic, but are either used in multiple places in a program or make using third-party libraries easier.  For Tidy, these include functions for dealing with &lt;a href="https://clang.llvm.org/docs/LibClang.html" rel="noopener noreferrer"&gt;Libclang&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generic utilities&lt;/strong&gt;.  For Tidy, these include macros, error-handling functions, string-handling functions, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test code&lt;/strong&gt;.  For Tidy, this includes a small unit-test framework, test executables, and a functional-test framework.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Program-Specific Data Structures and Algorithms
&lt;/h2&gt;

&lt;p&gt;As mentioned, Tidy includes a data structure to represent a symbol referenced in a 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="cm"&gt;/**
 * A symbol referenced in a translation unit.
 */&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="cm"&gt;/**
   * The symbol name with signature (for functions or operators, e.g.,
   * `sqrt(double)`) or template parameters (for templates, e.g.,
   * `std::set&amp;lt;T&amp;gt;`) used as a unique key since C++ allows overloaded
   * functions and specialized templates.
   */&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;key&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="cm"&gt;/**
   * The symbol name without signature (for functions or operators, e.g.,
   * `sqrt`) or template parameters (for templates, e.g., `std::set`)
   * used in `#include` comments.
   *
   * @note In C++, this is not guaranteed to be unique due to overloaded
   * functions and specialized templates.
   */&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="kt"&gt;unsigned&lt;/span&gt;    &lt;span class="n"&gt;ref_count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;              &lt;span class="c1"&gt;// Number of times referenced.&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The details of the structure isn’t important here.  What’s important is that &lt;code&gt;tidy_symbol&lt;/code&gt; and functions to access and manipulate symbols are declared in &lt;code&gt;symbol.h&lt;/code&gt; with definitions in &lt;code&gt;symbol.c&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As I wrote about in &lt;a href="https://dev.to/pauljlucas/include-tidy-a-tool-to-enforce-include-what-you-use-part-2-28nn"&gt;part 2&lt;/a&gt;, IWYU for C++ is much harder to do than for C.  I kept adding C++-specific functions to &lt;code&gt;symbol.c&lt;/code&gt; until that code comprised approximately one third of the total code.  I then decided to move all the C++-specific code to &lt;code&gt;cxx.c&lt;/code&gt; with declarations in &lt;code&gt;cxx.h&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If and when such a move is done is entirely subjective, but it puts all the C++-specific code in one place and removes all the C++-specific code from &lt;code&gt;symbol.c&lt;/code&gt; making the latter file easier to understand.&lt;/p&gt;

&lt;p&gt;The minor caveat of moving code is that the functions declared in &lt;code&gt;cxx.h&lt;/code&gt; can no longer be &lt;code&gt;static&lt;/code&gt;.  This exposes a deficiency in C that doesn’t support better “hiding.”  Ideally, the functions declared in &lt;code&gt;cxx.h&lt;/code&gt; should be visible only to the code in &lt;code&gt;symbol.c&lt;/code&gt;; but &lt;code&gt;static&lt;/code&gt; (internal linkage) works only for things in the &lt;em&gt;same&lt;/em&gt; &lt;code&gt;.c&lt;/code&gt; file and non-&lt;code&gt;static&lt;/code&gt; (external linkage) is “public.”  However, for a stand-alone program like Tidy, it doesn’t matter.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;But if you’re building a library, you ideally want to minimize the symbols that are public.  C++ does slightly better than C with namespaces and modules, but even those control only what other C++ code can access, not what symbols are public.  For both C and C++, you typically have to resort to compiler-specific attributes or visibility flags.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Tidy also needs some types and a data structure for representing 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="cm"&gt;/**
 * How to handle an include file.
 */&lt;/span&gt;
&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;tidy_handling&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;TIDY_HANDLE_DEFAULT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                &lt;span class="c1"&gt;// Default handling.&lt;/span&gt;
  &lt;span class="n"&gt;TIDY_HANDLE_ELIDE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                  &lt;span class="c1"&gt;// Elide even if necessary.&lt;/span&gt;
  &lt;span class="n"&gt;TIDY_HANDLE_KEEP&lt;/span&gt;                    &lt;span class="c1"&gt;// Keep even if unnecessary.&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Sorting "ranks" when includes are printed.
 *
 * @remarks In order for an include's sort_rank to default to
 * TIDY_SORT_DEFAULT, it's value should be 0 since the value of
 * members whose designated initializers are omitted defaults to 0.
 * Given that, the other values must be negative to sort before the
 * default.
 */&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="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;enum&lt;/span&gt;    &lt;span class="n"&gt;tidy_handling&lt;/span&gt;   &lt;span class="n"&gt;tidy_handling&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="cm"&gt;/**
 * A file that was included.
 */&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 that was 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 of file.&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 of file.&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, if any.&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 numbers included from.&lt;/span&gt;
  &lt;span class="n"&gt;tidy_handling&lt;/span&gt;   &lt;span class="n"&gt;handling&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;           &lt;span class="c1"&gt;// Handle specially?&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;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_needed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;          &lt;span class="c1"&gt;// Is this needed?&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;hash_table_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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly, &lt;code&gt;tidy_include&lt;/code&gt; and functions to access and manipulate includes are declared in &lt;code&gt;include.h&lt;/code&gt; with definitions in &lt;code&gt;include.c&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Eventually, it occurred to me that I’ll need a couple of other program specific data structures:&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="cm"&gt;/**
 * A source file extension and the language it corresponds to.
 */&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;tidy_file_ext&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;ext&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                  &lt;span class="c1"&gt;// Extension (without the `'.'`).&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;lang&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                 &lt;span class="c1"&gt;// Language: either `"c"` or `"c++"`.&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * An include path given via the `-I` command-line option.
 */&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;tidy_ipath&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;abs_path&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                 &lt;span class="c1"&gt;// The absolute path.&lt;/span&gt;
  &lt;span class="kt"&gt;size_t&lt;/span&gt;  &lt;span class="n"&gt;abs_path_len&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;             &lt;span class="c1"&gt;// Length of abs_path.&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Maps a cursor for either a libclang `TypedefDecl` or a `TypeAliasDecl`
 * to its scoped alias name.
 *
 * @remarks It's necessary to keep a map of cursors for type aliases
 * to their "pretty" scoped alias names.
 *
 * @par Example
 * @parblock
 * Given:
 *
 *      namespace std {
 *        // ...
 *        using ostream = basic_ostream&amp;lt;char&amp;gt;;
 *        // ...
 *      }
 *
 * the type_csr is the entire `using` declaration and alias_name is
 * `"std::ostream"`.  This mapping is needed to include the "pretty"
 * names in include comments.
 *
 * If the file being tidied uses `std::ostream` like:
 *
 *      void f( std::ostream&amp;amp; );
 *
 * then the symbol in the comment will be `std::ostream` and not
 * `std::basic_ostream`:
 *
 *      #include &amp;lt;ostream&amp;gt;          // std::ostream
 *
 * @endparblock
 */&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;tidy_typedef&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;CXCursor&lt;/span&gt;    &lt;span class="n"&gt;type_csr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;             &lt;span class="c1"&gt;// `TypedefDecl` or `TypeAliasDecl`.&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;alias_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;           &lt;span class="c1"&gt;// Scoped alias name.&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As before, declarations are in &lt;code&gt;file_ext.h&lt;/code&gt;, &lt;code&gt;ipaths.h&lt;/code&gt;, and &lt;code&gt;typedefs.h&lt;/code&gt; with definitions in &lt;code&gt;file_ext.c&lt;/code&gt;, &lt;code&gt;ipaths.c&lt;/code&gt;, and &lt;code&gt;typedefs.c&lt;/code&gt;, respectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generic Data Structures and Algorithms
&lt;/h2&gt;

&lt;p&gt;As mentioned previously, generic data structures like dynamic arrays, hash tables, red-black trees, and strings buffers are also needed since such things don’t exist in C’s standard library.  Each of these is in its own &lt;code&gt;.h&lt;/code&gt;/&lt;code&gt;.c&lt;/code&gt; pair, i.e., &lt;code&gt;array.h&lt;/code&gt; and &lt;code&gt;array.c&lt;/code&gt;, &lt;code&gt;hash_table.h&lt;/code&gt; and &lt;code&gt;hash_table.c&lt;/code&gt;, &lt;code&gt;red_black.h&lt;/code&gt; and &lt;code&gt;red_black.c&lt;/code&gt;, and &lt;code&gt;strbuf.h&lt;/code&gt; and &lt;code&gt;strbuf.c&lt;/code&gt;, respectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  Program Options
&lt;/h2&gt;

&lt;p&gt;As mentioned, these allow the behavior of your program to be changed.  For Tidy, these are declared in &lt;code&gt;options.h&lt;/code&gt; with definitions in &lt;code&gt;options.c&lt;/code&gt;.  Before the options themselves, we need a few additional types for some options:&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="cm"&gt;/**
 * Which symbols and in what order to include in a comment.
 */&lt;/span&gt;
&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;tidy_comment&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;TIDY_COMMENT_SYM_ALPHA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;               &lt;span class="c1"&gt;// Sorted alphabetically.&lt;/span&gt;
  &lt;span class="n"&gt;TIDY_COMMENT_SYM_LENGTH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;              &lt;span class="c1"&gt;// Sorted by name length, ascending.&lt;/span&gt;
  &lt;span class="n"&gt;TIDY_COMMENT_SYM_MOST_REF&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;            &lt;span class="c1"&gt;// Only most-referenced symbol.&lt;/span&gt;
  &lt;span class="n"&gt;TIDY_COMMENT_SYM_REF_COUNT&lt;/span&gt;            &lt;span class="c1"&gt;// Sorted by ref. count, descending.&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * When to exit with a non-zero status code.
 */&lt;/span&gt;
&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;tidy_error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;TIDY_ERROR_IF_VIOLATIONS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;             &lt;span class="c1"&gt;// Non-zero if violations.&lt;/span&gt;
  &lt;span class="n"&gt;TIDY_ERROR_ALWAYS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                    &lt;span class="c1"&gt;// Always exit with non-zero.&lt;/span&gt;
  &lt;span class="n"&gt;TIDY_ERROR_NEVER&lt;/span&gt;                      &lt;span class="c1"&gt;// Always exit with zero.&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Verbose mode.
 */&lt;/span&gt;
&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;tidy_verbose&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;TIDY_VERBOSE_NONE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                          &lt;span class="c1"&gt;// Don't be verbose.&lt;/span&gt;
  &lt;span class="n"&gt;TIDY_VERBOSE_ARGS&lt;/span&gt;                &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// Command-line arguments.&lt;/span&gt;
  &lt;span class="n"&gt;TIDY_VERBOSE_CONFIG_FILES&lt;/span&gt;        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&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="c1"&gt;// Configuration files.&lt;/span&gt;
  &lt;span class="n"&gt;TIDY_VERBOSE_CONFIG_SYMBOLS&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&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;// Configuration symbols.&lt;/span&gt;
  &lt;span class="n"&gt;TIDY_VERBOSE_CURSORS&lt;/span&gt;             &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// Libclang cursors.&lt;/span&gt;
  &lt;span class="n"&gt;TIDY_VERBOSE_DIRECTORY&lt;/span&gt;           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// Changing directory.&lt;/span&gt;
  &lt;span class="n"&gt;TIDY_VERBOSE_INCLUDES&lt;/span&gt;            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&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;// Files included.&lt;/span&gt;
  &lt;span class="n"&gt;TIDY_VERBOSE_PROXIES_EXPLICIT&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// Explicit include proxies.&lt;/span&gt;
  &lt;span class="n"&gt;TIDY_VERBOSE_PROXIES_IMPLICIT&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// Implicit include proxies.&lt;/span&gt;
  &lt;span class="n"&gt;TIDY_VERBOSE_SRC_FILE_VIOLATIONS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// Source file in violation.&lt;/span&gt;
  &lt;span class="n"&gt;TIDY_VERBOSE_SRC_FILE_ALWAYS&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// Always source file.&lt;/span&gt;
  &lt;span class="n"&gt;TIDY_VERBOSE_STATISTICS&lt;/span&gt;          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Print statistics?&lt;/span&gt;
  &lt;span class="n"&gt;TIDY_VERBOSE_SYMBOLS&lt;/span&gt;             &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;11&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="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;tidy_comment&lt;/span&gt; &lt;span class="n"&gt;tidy_comment&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_error&lt;/span&gt;   &lt;span class="n"&gt;tidy_error&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_verbose&lt;/span&gt; &lt;span class="n"&gt;tidy_verbose&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;tidy_verbose&lt;/code&gt; enumeration uses bit-flag values.  As I &lt;a href="https://dev.to/pauljlucas/enumerations-in-c-ae7"&gt;mentioned&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Rather than specify power-of-2 values explicitly, e.g., 0, 1, 2, 4, 8, etc., a common practice is to use &lt;code&gt;1 &amp;lt;&amp;lt; N&lt;/code&gt; where &lt;em&gt;N&lt;/em&gt; is the Nth bit from 0 to however many bits are needed and let the compiler do the calculation for you.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The options themselves are:&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;extern&lt;/span&gt; &lt;span class="kt"&gt;unsigned&lt;/span&gt;     &lt;span class="n"&gt;opt_align_column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;     &lt;span class="c1"&gt;// Comment alignment column.&lt;/span&gt;
&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="n"&gt;bool&lt;/span&gt;         &lt;span class="n"&gt;opt_all_includes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;     &lt;span class="c1"&gt;// Print all includes?&lt;/span&gt;
&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="n"&gt;color_when&lt;/span&gt;   &lt;span class="n"&gt;opt_color_when&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;       &lt;span class="c1"&gt;// When to colorize.&lt;/span&gt;
&lt;span class="k"&gt;extern&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;opt_comment_style&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="c1"&gt;// Comment delimiters to use.&lt;/span&gt;
&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="n"&gt;tidy_comment&lt;/span&gt; &lt;span class="n"&gt;opt_comment_symbols&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// How to list symbols in comments.&lt;/span&gt;
&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="n"&gt;bool&lt;/span&gt;         &lt;span class="n"&gt;opt_config_layers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c1"&gt;// Do configuration file layering?&lt;/span&gt;
&lt;span class="k"&gt;extern&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;opt_config_path&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;      &lt;span class="c1"&gt;// Configuration file path.&lt;/span&gt;
&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="n"&gt;bool&lt;/span&gt;         &lt;span class="n"&gt;opt_debug&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;            &lt;span class="c1"&gt;// Print debugging output?&lt;/span&gt;
&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="n"&gt;tidy_error&lt;/span&gt;   &lt;span class="n"&gt;opt_error&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;            &lt;span class="c1"&gt;// When to exit with non-zero.&lt;/span&gt;
&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="kt"&gt;unsigned&lt;/span&gt;     &lt;span class="n"&gt;opt_line_length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;      &lt;span class="c1"&gt;// Line length.&lt;/span&gt;
&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="n"&gt;tidy_verbose&lt;/span&gt; &lt;span class="n"&gt;opt_verbose&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;          &lt;span class="c1"&gt;// Print verbose output?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The option types are declared in &lt;code&gt;options.h&lt;/code&gt; and defined in &lt;code&gt;option.c&lt;/code&gt; along with functions to parse text and convert its value into a given option, that is for every option &lt;code&gt;opt_&lt;/code&gt;&lt;em&gt;X&lt;/em&gt;, there exists a function &lt;code&gt;opt_&lt;/code&gt;&lt;em&gt;X&lt;/em&gt;&lt;code&gt;_parse( char const* )&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Note that the task of getting option values from the user is separate since in Tidy’s case options can be set either from the command line or a configuration file.&lt;/p&gt;

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

&lt;p&gt;Most any non-trivial program (even a GUI program) has to parse the command-line for arguments and options.  While the arguments and options are program-specific, the &lt;a href="https://dev.to/pauljlucas/good-cli-design-implementation-h64"&gt;code to parse them is generally boilerplate&lt;/a&gt;.  The declarations for this code is in &lt;code&gt;options.h&lt;/code&gt; with definitions in &lt;code&gt;options.c&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuration File Parsing
&lt;/h2&gt;

&lt;p&gt;Many non-trivial programs also have to parse a configuration file.  Rather that use a Tidy-specific format, Tidy uses &lt;a href="https://toml.io/" rel="noopener noreferrer"&gt;TOML&lt;/a&gt;.  Completely generic TOML-parsing code is declared in &lt;code&gt;toml_lite.h&lt;/code&gt; with definitions in &lt;code&gt;toml_lite.c&lt;/code&gt; and code that uses it to parse TOML-specific configuration is declared in &lt;code&gt;config_file.h&lt;/code&gt; with definitions in &lt;code&gt;config_file.c&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;By splitting configuration file parsing into generic and program-specific components, the TOML parser can be reused elsewhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  Program-Specific Utilities
&lt;/h2&gt;

&lt;p&gt;Tidy has many functions that make using Libclang easier in a semi-specific yet generic way.  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="cm"&gt;/**
 * If \a cursor represents either a pointer or reference, gets the
 * cursor for the type to which it either points to or refers,
 * respectively.
 *
 * @param cursor The cursor.
 * @return Returns the cursor for the type to which \a cursor either
 * points to or refers, respectively; or \a cursor if it's neither
 * a pointer nor reference.
 */&lt;/span&gt;
&lt;span class="n"&gt;CXCursor&lt;/span&gt; &lt;span class="nf"&gt;tidy_Cursor_getUnderlyingType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;CXCursor&lt;/span&gt; &lt;span class="n"&gt;cursor&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, given a &lt;em&gt;cursor&lt;/em&gt; (Libclang’s term for a pointer to a particular node in the &lt;a href="https://en.wikipedia.org/wiki/Abstract_syntax_tree" rel="noopener noreferrer"&gt;AST&lt;/a&gt; of the parsed &lt;a href="https://en.wikipedia.org/wiki/Translation_unit_(programming)" rel="noopener noreferrer"&gt;translation unit&lt;/a&gt;) for a type like &lt;code&gt;T*&lt;/code&gt;, returns the cursor for &lt;code&gt;T&lt;/code&gt;.  Such a function is program-specific in that Tidy needs such a function, yet its implemented in a generic way such that &lt;em&gt;any&lt;/em&gt; program that needs such a function could use it.  Such functions are declared in &lt;code&gt;clang_util.h&lt;/code&gt; with definitions in &lt;code&gt;clang_util.c&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Even though I personally prefer using a more traditional K&amp;amp;R style of naming things using &lt;a href="https://en.wikipedia.org/wiki/Snake_case" rel="noopener noreferrer"&gt;snake case&lt;/a&gt;, Libclang uses an OOP version of &lt;a href="https://en.wikipedia.org/wiki/Camel_case" rel="noopener noreferrer"&gt;camel case&lt;/a&gt;.  I therefore named my utility functions to mimic Libclang’s style replacing the &lt;code&gt;clang_&lt;/code&gt; prefix with &lt;code&gt;tidy_&lt;/code&gt; to make it obvious that the function is &lt;em&gt;not&lt;/em&gt; in the Libclang library.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Generic Utilities
&lt;/h2&gt;

&lt;p&gt;Any non-trivial program eventually has a &lt;code&gt;util.h&lt;/code&gt; and &lt;code&gt;util.c&lt;/code&gt; pair containing miscellaneous, generic utilities, including &lt;a href="https://dev.to/pauljlucas/handy-cc-preprocessor-macros-27od"&gt;handy macros&lt;/a&gt; and functions.&lt;/p&gt;

&lt;p&gt;The important point is that nothing in those files should be specific to your program nor in any way depend on program-specific headers.  This makes them easy to copy into other programs as-is.&lt;/p&gt;

&lt;p&gt;If you have several related generic macros or functions, you might consider splitting those off into separate headers and corresponding &lt;code&gt;.c&lt;/code&gt; files.  For example, Tidy also has &lt;code&gt;type_traits.h&lt;/code&gt; containing several C++-like type-traits macros, &lt;code&gt;bit_util.h&lt;/code&gt; containing a few bit-testing functions, and &lt;code&gt;path_util.h&lt;/code&gt; contains several path-related functions.&lt;/p&gt;

&lt;p&gt;How many related macros or functions should you have before splitting them off?  It’s largely subjective, but I’d say at least three.&lt;/p&gt;

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

&lt;p&gt;I hope this extended example of how code was organized into source files in a mid-size program like Tidy helps you organize the code in your own programs.  While the example uses C, the components and organization apply to most any program in most any language.&lt;/p&gt;

</description>
      <category>c</category>
      <category>programming</category>
    </item>
    <item>
      <title>include-tidy: A Tool to Enforce Include-What-You-Use, Part 2</title>
      <dc:creator>Paul J. Lucas</dc:creator>
      <pubDate>Mon, 10 Aug 2026 12:11:09 +0000</pubDate>
      <link>https://dev.to/pauljlucas/include-tidy-a-tool-to-enforce-include-what-you-use-part-2-28nn</link>
      <guid>https://dev.to/pauljlucas/include-tidy-a-tool-to-enforce-include-what-you-use-part-2-28nn</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 described &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), a tool that enforces the &lt;em&gt;include-what-you-use&lt;/em&gt; (IWYU) principle for C and C++ programs, 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;The rules of the principle seem obvious and simple — trivial, even.  As I described previously, things like complete vs. incomplete types and preprocessor macros complicated the implementation somewhat, but not crazily so.&lt;/p&gt;

&lt;p&gt;I had done pretty the bulk of my testing on C source files including having Tidy run on itself. I (in what would turn out to be naively) thought that C++, at least in terms of referencing symbols and including the header files that declare them, would be largely the same.  That is, despite the huge language differences, in C++, symbols are still symbols and headers are still headers.&lt;/p&gt;

&lt;p&gt;Then out of the blue, someone e-mailed me a bug report for &lt;a href="https://github.com/paul-j-lucas/swishxx" rel="noopener noreferrer"&gt;SWISH++&lt;/a&gt; with a patch.  I had originally written SWISH++ back in the late ’90s, but hadn’t touched it in over a decade.  I decided to try Tidy on it.  I naturally expected &lt;em&gt;some&lt;/em&gt; IWYU violations, but I got &lt;em&gt;several dozen&lt;/em&gt;.  While surprising, I thought I’d just fix them.  After examining a few, I started to realize that applying IWYU to C++ is a &lt;em&gt;much&lt;/em&gt; harder problem!&lt;/p&gt;

&lt;p&gt;When writing C++ code and you need to refer to a symbol, you just instinctively include the header that defines it.  It turns out that actually codifying that instinct for C++ is &lt;em&gt;hard&lt;/em&gt; because there are actually several “obvious” exceptions to IWYU for C++ that simply don’t exist in C.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why IWYU for C++ is Harder
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Nested Types and Inheritance
&lt;/h3&gt;

&lt;p&gt;Probably the top two things that make IWYU for C++ hard are that C++ allows nested types and inheritance.  For example, given:&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="c1"&gt;// Base.hpp&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;value_type&lt;/span&gt; &lt;span class="o"&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;Base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;value_type&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kt"&gt;void&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;// ...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Derived.hpp&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;"Base.hpp"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;value_type&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Derived.cpp&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;"Derived.hpp"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;value_type&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;Base&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="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;d&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="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;Any C++ programmer would look at this code and say that the &lt;code&gt;#include&lt;/code&gt;s are exactly they way they should be: &lt;code&gt;Derived.cpp&lt;/code&gt; implements functions for &lt;code&gt;Derived&lt;/code&gt; so it includes &lt;code&gt;Derived.hpp&lt;/code&gt;; &lt;code&gt;Derived.hpp&lt;/code&gt; derives from &lt;code&gt;Base&lt;/code&gt; so it includes &lt;code&gt;Base.hpp&lt;/code&gt;; no more, no less.  Easy, peasy.&lt;/p&gt;

&lt;p&gt;But &lt;code&gt;Derived.cpp&lt;/code&gt; directly references &lt;code&gt;value_type&lt;/code&gt;, &lt;code&gt;Base&lt;/code&gt;, and &lt;code&gt;b()&lt;/code&gt;, all of which are declared in &lt;code&gt;Base.hpp&lt;/code&gt;.  So if you naively enforce IWYU, you’d say that &lt;code&gt;Derived.cpp&lt;/code&gt; must include &lt;code&gt;Base.hpp&lt;/code&gt;.  Except no C++ programmer would think that because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Derived.cpp&lt;/code&gt; includes &lt;code&gt;Derived.hpp&lt;/code&gt; that defines &lt;code&gt;Derived&lt;/code&gt; that inherits &lt;code&gt;value_type&lt;/code&gt; from &lt;code&gt;Base&lt;/code&gt;.  In order to declare &lt;code&gt;Derived&lt;/code&gt; in the first place, &lt;code&gt;Derived.hpp&lt;/code&gt; &lt;em&gt;had&lt;/em&gt; to include &lt;code&gt;Base.hpp&lt;/code&gt; because &lt;code&gt;Derived&lt;/code&gt; is-a &lt;code&gt;Base&lt;/code&gt;.  Hence, the &lt;em&gt;transitive&lt;/em&gt; include of &lt;code&gt;Base.hpp&lt;/code&gt; into &lt;code&gt;Derived.cpp&lt;/code&gt; is sufficient.&lt;/li&gt;
&lt;li&gt;The same is true for &lt;code&gt;Base&lt;/code&gt; and &lt;code&gt;b()&lt;/code&gt;: the transitive include of &lt;code&gt;Base.hpp&lt;/code&gt; is sufficient.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In C, neither nested types nor inheritance exist, so neither do these cases.&lt;/p&gt;

&lt;h3&gt;
  
  
  Functions and Derived Arguments
&lt;/h3&gt;

&lt;p&gt;Consider this addition to the previous example:&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="c1"&gt;// Base.hpp&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;

&lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="k"&gt;operator&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Derived.cpp&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&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="n"&gt;Derived&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&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;Derived&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;j&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;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;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly to before, &lt;code&gt;Derived.cpp&lt;/code&gt; directly references &lt;code&gt;operator==()&lt;/code&gt; that’s declared in &lt;code&gt;Base.hpp&lt;/code&gt;. So again, if you naively enforce IWYU, you’d say that &lt;code&gt;Derived.cpp&lt;/code&gt; must include &lt;code&gt;Base.hpp&lt;/code&gt;. Except again, no C++ programmer would think that because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Derived&lt;/code&gt; is-a &lt;code&gt;Base&lt;/code&gt; and in order to declare &lt;code&gt;Derived&lt;/code&gt; in the first place, &lt;code&gt;Derived.hpp&lt;/code&gt; &lt;em&gt;had&lt;/em&gt; to include &lt;code&gt;Base.hpp&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The inheritance means that any operator (or function) that accepts a &lt;code&gt;Base&lt;/code&gt; as an argument should also accept &lt;code&gt;Derived&lt;/code&gt; as an argument.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Again, this means that the transitive include of &lt;code&gt;Base.hpp&lt;/code&gt; is sufficient.&lt;/p&gt;

&lt;p&gt;Specifically, for any function (or operator) &lt;code&gt;f&lt;/code&gt;, you can’t decide immediately whether the header that declares it is required.  Instead, you have to defer it until after you’ve examined all of its arguments.  If the function:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Has one or more arguments; and:&lt;/li&gt;
&lt;li&gt;At least one of those arguments’ type is derived from a relevant base.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;then the header is &lt;em&gt;not&lt;/em&gt; required: again, the transitive include is sufficient.  Similarly in C, this case doesn’t exist: if you reference a function, then the header that declares it is required — period.&lt;/p&gt;

&lt;h3&gt;
  
  
  Nested Types and Aliases
&lt;/h3&gt;

&lt;p&gt;Consider this example:&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="c1"&gt;// int_set.hpp&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;set&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;int_set&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Foo.cpp&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;"int_set.hpp"&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&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;int_set&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;value_type&lt;/span&gt; &lt;span class="n"&gt;v&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;&lt;code&gt;Foo.cpp&lt;/code&gt; directly references &lt;code&gt;value_type&lt;/code&gt; that’s declared in &lt;code&gt;&amp;lt;set&amp;gt;&lt;/code&gt;.  In this case, there is no inheritance at all, just a type alias.  So again, if you naively enforce IWYU, you’d say that &lt;code&gt;Foo.cpp&lt;/code&gt; must include &lt;code&gt;&amp;lt;set&amp;gt;&lt;/code&gt;. Except again, no C++ programmer would think that because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In order to declare &lt;code&gt;int_set&lt;/code&gt; in the first place, &lt;code&gt;int_set.hpp&lt;/code&gt; had to include &lt;code&gt;&amp;lt;set&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;That aside, the point of using a type alias is to hide what the underlying type is, hence the fact that &lt;code&gt;int_set&lt;/code&gt; is-a &lt;code&gt;std::set&lt;/code&gt; should be irrelevant.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Therefore, &lt;code&gt;Foo.cpp&lt;/code&gt; should not be required to include &lt;code&gt;&amp;lt;set&amp;gt;&lt;/code&gt;; again, its transitive include is sufficient.&lt;/p&gt;

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

&lt;p&gt;Implementing IWYU for C++ turned out to be a &lt;em&gt;much&lt;/em&gt; harder problem that I originally thought several months ago.&lt;/p&gt;

&lt;p&gt;I’ve recently released &lt;code&gt;include-tidy&lt;/code&gt; 2.0 that has &lt;em&gt;vastly&lt;/em&gt; improved C++ support. Even though SWISH++ now has no IWYU violations, it was written in an older version of C++.  As time permits, I’ll modernize the code to a more recent version of C++ and won’t be surprised if there are other special case exceptions to IWYU for C++.&lt;/p&gt;

</description>
      <category>cpp</category>
    </item>
    <item>
      <title>Into the void</title>
      <dc:creator>Paul J. Lucas</dc:creator>
      <pubDate>Sat, 08 Aug 2026 02:23:26 +0000</pubDate>
      <link>https://dev.to/pauljlucas/into-the-void-4h69</link>
      <guid>https://dev.to/pauljlucas/into-the-void-4h69</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;static&lt;/code&gt; keyword is often cited as the most over-used keyword in C and C++.  In C, there are three uses.  I only recently realized that the &lt;code&gt;void&lt;/code&gt; keyword has &lt;em&gt;four&lt;/em&gt; uses.  I mean, I knew the four circumstances in which you’d use &lt;code&gt;void&lt;/code&gt;, but it never “clicked” in my head that there were &lt;em&gt;four&lt;/em&gt; uses — and that’s greater than &lt;code&gt;static&lt;/code&gt;’s three.  I think it’s because all of &lt;code&gt;void&lt;/code&gt;’s uses are somewhat related to “nothingness” whereas &lt;code&gt;static&lt;/code&gt;’s uses are largely unrelated, hence more noticeable.&lt;/p&gt;

&lt;h2&gt;
  
  
  History
&lt;/h2&gt;

&lt;p&gt;Originally, C didn’t have the &lt;code&gt;void&lt;/code&gt; keyword.  To write a function that didn’t return a value, you could simply omit the return 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="n"&gt;print_locus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&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;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;msg&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;"%s:%d,%d: %s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&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 function is written in the original “K&amp;amp;R” dialect of C — before function prototypes were adopted from C++ — where parameters were specified twice: the first time for the order, and the second time for the types.  Any parameter not explicitly given a type was presumed to be &lt;code&gt;int&lt;/code&gt;; any function not explicitly given a return type was presumed to return &lt;code&gt;int&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You could even omit the &lt;code&gt;return&lt;/code&gt; statement.  In those days, C compilers were fairly lax about enforcing things (hence the creation of &lt;a href="https://en.wikipedia.org/wiki/Lint_(software)" rel="noopener noreferrer"&gt;lint&lt;/a&gt;). But the compiler still generated a machine instruction to return a (garbage) value.  Since the caller wasn’t expecting a return value anyway, it worked out.  If you wanted to write marginally cleaner code, you’d just &lt;code&gt;return 0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This state of affairs, specifically that there was no way to state explicitly that a function returned no value, annoyed &lt;a href="https://en.wikipedia.org/wiki/Stephen_R._Bourne" rel="noopener noreferrer"&gt;Stephen Bourne&lt;/a&gt; (yes, the creator of the &lt;a href="https://en.wikipedia.org/wiki/Bourne_shell" rel="noopener noreferrer"&gt;Bourne Shell&lt;/a&gt;).  After &lt;a href="https://www.youtube.com/watch?v=2kEJoWfobpA&amp;amp;t=2857s" rel="noopener noreferrer"&gt;complaining&lt;/a&gt; to &lt;a href="https://en.wikipedia.org/wiki/Dennis_Ritchie" rel="noopener noreferrer"&gt;Ritchie&lt;/a&gt;, and Ritchie realizing that not returning anything from a function could save one machine instruction, &lt;code&gt;void&lt;/code&gt; (Bourne’s suggested name) was added to C.&lt;/p&gt;

&lt;p&gt;Since then, &lt;code&gt;void&lt;/code&gt; slowly had use-cases added to it.  It’s also influenced and been adopted by other languages including C++ (obviously), C#, Java, D, and Swift (though Swift spells it &lt;code&gt;Void&lt;/code&gt; with a capital “V”).&lt;/p&gt;

&lt;h2&gt;
  
  
  Function Prototypes
&lt;/h2&gt;

&lt;p&gt;Perhaps the biggest influence C++ had on C was the &lt;a href="https://en.wikipedia.org/wiki/Backporting" rel="noopener noreferrer"&gt;backporting&lt;/a&gt; of &lt;a href="https://en.wikipedia.org/wiki/Function_prototype" rel="noopener noreferrer"&gt;function prototypes&lt;/a&gt;.  In K&amp;amp;R C, if you &lt;em&gt;declared&lt;/em&gt; (not defined) a function at all, it was only because it returned a type other than &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="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// K&amp;amp;R C: no parameter information!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Function declarations declared &lt;em&gt;only&lt;/em&gt; its return type; its parameters were not declared at all. You just had to ensure that &lt;em&gt;you&lt;/em&gt; called the function with the right types.&lt;/p&gt;

&lt;p&gt;C++ added function prototypes because &lt;a href="https://en.wikipedia.org/wiki/Bjarne_Stroustrup" rel="noopener noreferrer"&gt;Bjarne&lt;/a&gt; wanted the ability to overload functions based on their arguments.  But prototypes are also very useful for ensuring that the number and types of arguments actually match a function’s parameters. Hence, they were back-ported to C.&lt;/p&gt;

&lt;p&gt;But in C++, a function declared like &lt;code&gt;f()&lt;/code&gt; means &lt;code&gt;f&lt;/code&gt; takes no parameters whereas in K&amp;amp;R C, all it meant was that &lt;code&gt;f&lt;/code&gt; was a function (with no information about its parameters at all).&lt;/p&gt;

&lt;p&gt;To add prototypes to C yet still allow existing C code for backwards compatibility, &lt;code&gt;void&lt;/code&gt; was re-used, e.g., &lt;code&gt;f(void)&lt;/code&gt; means &lt;code&gt;f&lt;/code&gt; takes no parameters in C — not that &lt;code&gt;f&lt;/code&gt; takes one parameter of type &lt;code&gt;void&lt;/code&gt; since you can’t declare either a variable or parameter of type &lt;code&gt;void&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To increase compatibility between C and C++ header files, &lt;code&gt;f(void)&lt;/code&gt; means the same thing in C++ though the use of &lt;code&gt;void&lt;/code&gt; is otherwise unnecessary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pointers
&lt;/h2&gt;

&lt;p&gt;Although &lt;code&gt;void&lt;/code&gt; objects can’t exist, you curiously can have pointers to &lt;code&gt;void&lt;/code&gt;, e.g., &lt;code&gt;void *p&lt;/code&gt;.  Such pointers are use to point to anything (the opposite of nothing), but the actual type is unknown.  As such, you can never dereference a &lt;code&gt;void&lt;/code&gt; pointer.&lt;/p&gt;

&lt;p&gt;Before &lt;code&gt;void&lt;/code&gt; in K&amp;amp;R C, &lt;code&gt;char*&lt;/code&gt;, in addition to pointing at either a single character or more commonly an array of characters, i.e., a string, was also used to point to anything, i.e., a chunk of bytes. However, using &lt;code&gt;void*&lt;/code&gt; is much clearer (even though you often have to cast a &lt;code&gt;void*&lt;/code&gt; to a &lt;code&gt;char*&lt;/code&gt; anyway so you can increment it).&lt;/p&gt;

&lt;h2&gt;
  
  
  Casting
&lt;/h2&gt;

&lt;p&gt;The last use is casting to &lt;code&gt;void&lt;/code&gt;. There are actually two use-cases.  One is making it clear that you’re intentionally discarding the return value of a function (that doesn’t return &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="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;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s"&gt;"hello, world!&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Such a use means you’re calling the function only for its side effects.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Did you even realize that &lt;code&gt;printf&lt;/code&gt; returns a value?  It returns the number of characters printed.  This can actually be useful when you’re trying to line-up columns in multiple lines of output.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Such a use is rare and is mostly for the benefit of the human reader, not the compiler.  One exception is if the function is declared &lt;a href="https://en.cppreference.com/c/language/attributes/nodiscard" rel="noopener noreferrer"&gt;&lt;code&gt;[[nodiscard]]&lt;/code&gt;&lt;/a&gt;, but you want to discard its return value anyway.&lt;/p&gt;

&lt;p&gt;The other use-case is casting a parameter to &lt;code&gt;void&lt;/code&gt; as is done &lt;a href="https://github.com/paul-j-lucas/cdecl/blob/45dad5227c60fe6a1fa42635e2eeda7de59238f2/src/c_ast_check.c#L3125" rel="noopener noreferrer"&gt;here&lt;/a&gt; in &lt;a href="https://github.com/paul-j-lucas/cdecl" rel="noopener noreferrer"&gt;&lt;code&gt;cdecl&lt;/code&gt;&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="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;c_ast_visitor_type&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="k"&gt;const&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="n"&gt;user_data_t&lt;/span&gt; &lt;span class="n"&gt;user_data&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;user_data&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;This means that you’re intentionally not using the value of a parameter, i.e., casting its value to “nothing.”  This also suppresses a warning that the parameter isn’t used.  (In &lt;a href="https://en.wikipedia.org/wiki/C23_(C_standard_revision)" rel="noopener noreferrer"&gt;C23&lt;/a&gt;, you can simply omit the parameter’s name; in C++, you always could.)&lt;/p&gt;

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

&lt;p&gt;So now you know that &lt;code&gt;void&lt;/code&gt;, not &lt;code&gt;static&lt;/code&gt;, is the most over-used in C.  The reason for over-use of keywords in general is that adding any new keyword to a language breaks existing programs because somebody, somewhere, used it to name something.  In &lt;code&gt;void&lt;/code&gt;’s case, the different uses are at least mostly related to “nothingness.”&lt;/p&gt;

</description>
      <category>c</category>
      <category>cpp</category>
    </item>
    <item>
      <title>A Generic min Function in C</title>
      <dc:creator>Paul J. Lucas</dc:creator>
      <pubDate>Sun, 05 Jul 2026 13:57:28 +0000</pubDate>
      <link>https://dev.to/pauljlucas/a-generic-min-function-in-c-3koh</link>
      <guid>https://dev.to/pauljlucas/a-generic-min-function-in-c-3koh</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;If you’ve programmed any length of time in C, you’ve likely written a macro that returns the minimum of two values 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 MIN(I,J)  ((I) &amp;lt; (J) ? (I) : (J))
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As I’ve explained in the &lt;a href="https://dev.to/pauljlucas/cc-preprocessor-macros-fh5"&gt;macro article&lt;/a&gt;, all those parentheses should be used to ensure operator precedence as you expect.  Even so, the problem of side effects occurring multiple times is still a problem:&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;mf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MIN&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;g&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// either f or g called twice&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;mn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MIN&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="n"&gt;j&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;    &lt;span class="c1"&gt;// undefined behavior&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second example above is worse because incrementing the same variable more than once in the same expression results in &lt;a href="https://dev.to/pauljlucas/undefined-behavior-in-c-and-c-3a20"&gt;undefined behavior&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;To eliminate side effects occurring more than once, a function can be used instead.  But because C lacks templates like C++, multiple functions need to be written.  At a minimum, you need:&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="kt"&gt;long&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="nf"&gt;min_ll&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;j&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;j&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;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&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="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="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="nf"&gt;min_ull&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;j&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;j&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;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&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="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="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;min_d&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;i&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;j&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;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&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="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="kt"&gt;long&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;min_ld&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;double&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="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;j&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;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where &lt;code&gt;min_ll&lt;/code&gt; will handle all signed integers, &lt;code&gt;min_ull&lt;/code&gt; will handle all unsigned integers, &lt;code&gt;min_d&lt;/code&gt; will handle &lt;code&gt;float&lt;/code&gt; and &lt;code&gt;double&lt;/code&gt;, and &lt;code&gt;min_ld&lt;/code&gt; will handle &lt;code&gt;long double&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We’re going to ignore &lt;a href="https://www.cppreference.com/c/language/arithmetic_types#Complex_floating_types" rel="noopener noreferrer"&gt;&lt;code&gt;_Complex&lt;/code&gt;&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. &lt;code&gt;_Complex&lt;/code&gt; is typically used only in specialized programs for math or physics, and the decimal types are typically used only in finance. If wanted, they’re left as trivial exercises for the reader.&lt;/p&gt;

&lt;p&gt;You &lt;em&gt;could&lt;/em&gt; use &lt;code&gt;min_ld&lt;/code&gt; to handle both &lt;code&gt;float&lt;/code&gt; and &lt;code&gt;double&lt;/code&gt;, but &lt;code&gt;long double&lt;/code&gt; is typically less performant than either, so casting all floating point values to &lt;code&gt;long double&lt;/code&gt; isn’t a good idea.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;These should be declared &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; and put into a header (&lt;code&gt;.h&lt;/code&gt;) file.  You can get away with making them &lt;code&gt;static&lt;/code&gt; rather than having to use &lt;code&gt;extern inline&lt;/code&gt; in a &lt;code&gt;.c&lt;/code&gt; file since no self-respecting C compiler will refuse to inline such trivial functions at least with optimization.&lt;/p&gt;

&lt;p&gt;If you want to reduce the verbosity, you can use a helper macro 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 MIN_IMPL(T,SUFFIX) \
  static inline T min_##SUFFIX( T i, T j ) { return i &amp;lt; j ? i : j; }
&lt;/span&gt;
&lt;span class="n"&gt;MIN_IMPL&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="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ll&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;MIN_IMPL&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="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ull&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;MIN_IMPL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;MIN_IMPL&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;double&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ld&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="cp"&gt;#undef MIN_IMPL
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;_Generic&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Additionally, &lt;a href="https://dev.to/pauljlucas/generic-in-c-i48"&gt;&lt;code&gt;_Generic&lt;/code&gt;&lt;/a&gt; can be used to give a veneer of function overloading so that we can simply write:&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;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;min&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;j&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 will “just work” regardless of the types of &lt;code&gt;i&lt;/code&gt; and &lt;code&gt;j&lt;/code&gt;. Here’s the macro:&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 min(I,J)                  \
  _Generic( (I) + (J),            \
    int               : min_ll,   \
    long              : min_ll,   \
    long long         : min_ll,   \
    unsigned int      : min_ull,  \
    unsigned long     : min_ull,  \
    unsigned long long: min_ull,  \
    float             : min_d,    \
    double            : min_d,    \
    long double       : min_ld    \
  )( (I), (J) )
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;(I) + (J)&lt;/code&gt; is a common trick with &lt;code&gt;_Generic&lt;/code&gt; to use the “usual arithmetic conversions” to determine the common type when the types of &lt;code&gt;I&lt;/code&gt; and &lt;code&gt;J&lt;/code&gt; are not the same. (As a reminder, &lt;code&gt;_Generic&lt;/code&gt; does &lt;em&gt;not&lt;/em&gt; evaluate the expression just like &lt;a href="https://en.cppreference.com/c/language/sizeof" rel="noopener noreferrer"&gt;&lt;code&gt;sizeof&lt;/code&gt;&lt;/a&gt; doesn’t.) The trick also promotes smaller integral types like &lt;code&gt;char&lt;/code&gt; and &lt;code&gt;short&lt;/code&gt; to &lt;code&gt;int&lt;/code&gt; (or to &lt;code&gt;unsigned int&lt;/code&gt; if &lt;code&gt;char&lt;/code&gt; is unsigned) so we don’t need explicit cases for those.&lt;/p&gt;

&lt;p&gt;Some astute readers might object and ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Doesn’t referencing function names in the expressions cause their addresses to be taken thereby preventing the compiler from inlining calls to them because they’re now being called via pointers-to-function?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Fortunately, &lt;a href="https://godbolt.org/z/vMjrd194G" rel="noopener noreferrer"&gt;no&lt;/a&gt;. Remember that &lt;code&gt;_Generic&lt;/code&gt; happens at &lt;em&gt;compile time&lt;/em&gt;, so in this case, the compiler substitutes the entire &lt;code&gt;_Generic&lt;/code&gt; expression with a direct call to the chosen inline function.&lt;/p&gt;

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

&lt;p&gt;Using &lt;code&gt;_Generic&lt;/code&gt; and the usual arithmetic conversions, a minimal, type-safe, undefined-behavior-safe &lt;code&gt;min&lt;/code&gt; function can be implemented in C.&lt;/p&gt;

</description>
      <category>c</category>
    </item>
    <item>
      <title>Another Tale of Two Threads (C or C++ vs. Python)</title>
      <dc:creator>Paul J. Lucas</dc:creator>
      <pubDate>Fri, 03 Jul 2026 13:44:33 +0000</pubDate>
      <link>https://dev.to/pauljlucas/another-tale-of-two-threads-c-or-c-vs-python-hhl</link>
      <guid>https://dev.to/pauljlucas/another-tale-of-two-threads-c-or-c-vs-python-hhl</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This article is sort-of a sequel to &lt;a href="https://dev.to/pauljlucas/a-tale-of-two-threads-apis-2m32"&gt;A Tale of Two Threads (APIs)&lt;/a&gt;, but this time it’s about a significant difference between either C or C++ and Python threads.  If you’re either a C or C++ programmer who’s dabbling with Python threads, you should be aware of what follows.&lt;/p&gt;

&lt;p&gt;For the purposes of this article, all of POSIX threads (aka, &lt;a href="https://en.wikipedia.org/wiki/Pthreads" rel="noopener noreferrer"&gt;pthreads&lt;/a&gt;), &lt;a href="https://cppreference.com/c/thread" rel="noopener noreferrer"&gt;standard C threads&lt;/a&gt;, and &lt;a href="https://cppreference.com/cpp/thread" rel="noopener noreferrer"&gt;standard C++ threads&lt;/a&gt; can be considered equivalent and will all be referred to simply as pthreads.  (On POSIX systems, both C and C++ threads are typically implemented as a thin layer on top of pthreads anyway.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;During my career, I’ve mostly used pthreads from either C or C++ programs. I’m not a Python expert.  At most, I’ve written a handful of scripts in Python, the longest of which was around 350 lines, and none used threads.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I have a love-hate relationship with Python. No, it has nothing to do with Python using the &lt;a href="https://en.wikipedia.org/wiki/Off-side_rule" rel="noopener noreferrer"&gt;off-side rule&lt;/a&gt;. Primarily, I dislike that Python isn’t statically typed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In late 2024 (after officially &lt;a href="https://dev.to/pauljlucas/career-retrospective-1ojp"&gt;retiring&lt;/a&gt;), I agreed to do some work part-time for an application written in Python that necessarily makes heavy use of threads.  Python has its own &lt;a href="https://docs.python.org/3/library/threading.html" rel="noopener noreferrer"&gt;threading library&lt;/a&gt; that looks like pretty much every other threading library and apparently contains no surprises for a C or C++ programmer. &lt;em&gt;Apparently&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Threads in C and C++
&lt;/h2&gt;

&lt;p&gt;Either a C or C++ programmer would know that when either:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;main()&lt;/code&gt; returns; or:&lt;/li&gt;
&lt;li&gt;Any function calls &lt;a href="https://cppreference.com/c/program/exit" rel="noopener noreferrer"&gt;&lt;code&gt;exit&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;then the entire process terminates immediately.*&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;* In C and C++, &lt;a href="https://en.cppreference.com/c/program/atexit" rel="noopener noreferrer"&gt;&lt;code&gt;atexit&lt;/code&gt;&lt;/a&gt; handlers are performed before termination; in C++, destructors for global objects are also performed. But this doesn’t matter for this article.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As I previously wrote:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Even though nascent “threads” appeared as early as 1966, they weren’t supported by any major programming language of that era. POSIX threads, aka pthreads (“pea-threads”), didn't appear until 1995. Consequently when C was created in 1972, it didn’t support threads at all until pthreads came along. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;One consequence of this is that the addition of pthreads couldn’t change the behavior of either 1 or 2 above, that is the process still terminates &lt;strong&gt;&lt;em&gt;even if other threads are still running&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;To prevent #1 from happening, the main thread (which is the thread &lt;code&gt;main&lt;/code&gt; runs on) has to &lt;a href="https://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_join.html" rel="noopener noreferrer"&gt;join&lt;/a&gt; every thread it created.&lt;/p&gt;

&lt;h2&gt;
  
  
  Threads in Python
&lt;/h2&gt;

&lt;p&gt;The significant difference in Python is that the main thread will wait until all (non-daemon) threads have terminated, i.e., it does an implicit join on all of them.&lt;/p&gt;

&lt;p&gt;Consequently, this means that, unless you either need to synchronize with or want the return values from threads’ main functions, you don’t need to join them yourself explicitly.&lt;/p&gt;

&lt;p&gt;If you’re a native Python programmer, this likely isn’t news to you; but for a C or C++ programmer, it might be. It was to me.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;As it happens, Java handles threads the same way as Python.  Go and Rust handle threads the same way as C and C++.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;If you’re doing thread programming and are coming from either C or C++ to Python, know that process lifetime is handled differently.&lt;/p&gt;

&lt;p&gt;Why does Python (and Java) handle threads differently?  On the whole, the behavior makes thread programming slightly easier.&lt;/p&gt;

</description>
      <category>c</category>
      <category>cpp</category>
      <category>python</category>
    </item>
    <item>
      <title>Pointers and Tuning and Loops! Oh My!</title>
      <dc:creator>Paul J. Lucas</dc:creator>
      <pubDate>Thu, 18 Jun 2026 21:34:39 +0000</pubDate>
      <link>https://dev.to/pauljlucas/pointers-and-tuning-and-loops-oh-my-5e09</link>
      <guid>https://dev.to/pauljlucas/pointers-and-tuning-and-loops-oh-my-5e09</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;While all code should be efficient, code for library-like components, especially involving loops, should be as efficient as possible since such code is often widely used.&lt;/p&gt;

&lt;p&gt;In my &lt;a href="https://dev.to/pauljlucas/a-simple-dynamic-array-for-c-1k24"&gt;A Simple Dynamic Array for C&lt;/a&gt;, I included the source code for a function to clean-up 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="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;While this code is correct and good enough for pedagogical purposes, it’s not optimal. Before I tell you why, see if you can figure out why. Hint: it has to do with the use of both the &lt;code&gt;array&lt;/code&gt; pointer and the function call in the loop.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For those who might not get the reference in this article’s title, it’s a play on a line from &lt;a href="https://www.imdb.com/title/tt0032138/" rel="noopener noreferrer"&gt;The Wizard of Oz&lt;/a&gt;. The original line was “Lions and tigers and bears! Oh, my!”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Loop Refresher
&lt;/h2&gt;

&lt;p&gt;In C (and languages inspired by C including C++, C#, Go, and Java), &lt;code&gt;for&lt;/code&gt; loop conditions are reevaluated on &lt;em&gt;every&lt;/em&gt; loop iteration.  For example, 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;for&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="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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the condition &lt;code&gt;i &amp;lt; n&lt;/code&gt; is evaluated on every iteration.  That means if &lt;code&gt;n&lt;/code&gt; is changed within the loop, it could terminate either earlier or later than it was initially supposed to — and this is well-defined behavior.&lt;/p&gt;

&lt;p&gt;This is in contrast to some older languages like Fortran and Pascal as well as some newer languages like Rust where the loop’s termination value is evaluated &lt;em&gt;once&lt;/em&gt; just prior to the start of the loop.  For example, in Pascal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is actually treated as if it were this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="n"&gt;limit&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="n"&gt;limit&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that if the loop condition is a more complicated expression, such as calling a 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="k"&gt;for&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="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;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then the function will be called on &lt;em&gt;every&lt;/em&gt; loop iteration.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Except if the function is marked as &lt;a href="https://www.cppreference.com/c/language/attributes/unsequenced" rel="noopener noreferrer"&gt;&lt;code&gt;unsequenced&lt;/code&gt;&lt;/a&gt; in &lt;a href="https://en.wikipedia.org/wiki/C23_(C_standard_revision)" rel="noopener noreferrer"&gt;C23&lt;/a&gt; in which case the compiler can &lt;a href="https://en.wikipedia.org/wiki/Loop-invariant_code_motion" rel="noopener noreferrer"&gt;hoist&lt;/a&gt; its call out of the loop.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;(Have you figured out the “why” yet?)&lt;/p&gt;

&lt;h2&gt;
  
  
  Pointers
&lt;/h2&gt;

&lt;p&gt;Wherever pointers are involved, things get more complicated. From an optimization perspective, pointers are like sand in your gears.  Returning to the loop in &lt;code&gt;array_cleanup&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;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That gets compiled by &lt;code&gt;clang&lt;/code&gt; into this x86-64 assembly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.LBB0_4:
    mov  rdi, r15
    call r14                       ; (*free_fn)( element )
    add  r15, qword ptr [rbx + 8]  ; element += array-&amp;gt;esize
    inc  r12                       ; ++i
    cmp  r12, qword ptr [rbx + 16] ; i &amp;lt; array-&amp;gt;len
    jb   .LBB0_4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The things to notice are the &lt;code&gt;qword ptr&lt;/code&gt; lines which means the code has to dereference &lt;code&gt;array&lt;/code&gt; (which means read from memory) &lt;em&gt;twice&lt;/em&gt; on &lt;em&gt;every&lt;/em&gt; iteration.  That’s slow.&lt;/p&gt;

&lt;p&gt;The problem is that the compiler can’t know for &lt;em&gt;sure&lt;/em&gt; that the array object pointed to by &lt;code&gt;array&lt;/code&gt; isn’t modified by the function pointed to by &lt;code&gt;free_fn&lt;/code&gt;.  For all the compiler knows, the function has access to a global copy of the pointer and &lt;em&gt;could&lt;/em&gt; modify the array.  Compilers &lt;em&gt;have&lt;/em&gt; to play it safe.&lt;/p&gt;

&lt;p&gt;If there were no function call in the loop, then the compiler could safely hoist both &lt;code&gt;len&lt;/code&gt; and &lt;code&gt;esize&lt;/code&gt; outside the loop as if the code were:&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;size_t&lt;/span&gt; &lt;span class="k"&gt;const&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;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="kt"&gt;size_t&lt;/span&gt; &lt;span class="k"&gt;const&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&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;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;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="c1"&gt;// ... do something other than call a function ...&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;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;At best, the compiler can put &lt;code&gt;esize&lt;/code&gt; and &lt;code&gt;len&lt;/code&gt; into registers; but even at worst, if the compiler puts them into local variables, it would still save two pointer dereferences per iteration.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;restrict&lt;/code&gt; Revisited
&lt;/h2&gt;

&lt;p&gt;Is there any way to tell the compiler that &lt;code&gt;free_fn&lt;/code&gt; won’t modify the array?  Why yes, there is: &lt;a href="https://en.cppreference.com/c/language/restrict" rel="noopener noreferrer"&gt;&lt;code&gt;restrict&lt;/code&gt;&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;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="kr"&gt;restrict&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="c1"&gt;// ... otherwise the same as before ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(If you are unfamiliar with &lt;code&gt;restrict&lt;/code&gt;, you should read my previous &lt;a href="https://dev.to/pauljlucas/the-obscure-restrict-keyword-in-c-2541"&gt;article&lt;/a&gt; about it first.)&lt;/p&gt;

&lt;p&gt;Even if you are familiar with &lt;code&gt;restrict&lt;/code&gt;, you may be surprised to learn that it can help in this case.  The canonical use case for &lt;code&gt;restrict&lt;/code&gt; is &lt;a href="https://pubs.opengroup.org/onlinepubs/9699919799/functions/memcpy.html" rel="noopener noreferrer"&gt;&lt;code&gt;memcpy&lt;/code&gt;&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;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;memcpy&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="kr"&gt;restrict&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;void&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kr"&gt;restrict&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where there are &lt;em&gt;two&lt;/em&gt; pointers marked &lt;code&gt;restrict&lt;/code&gt; which means that they do &lt;em&gt;not&lt;/em&gt; point to overlapping regions of memory, i.e., they don’t overlap with each other.&lt;/p&gt;

&lt;p&gt;But in the case of &lt;code&gt;array&lt;/code&gt;, how can &lt;code&gt;restrict&lt;/code&gt; help when there is no other pointer in &lt;code&gt;array_cleanup&lt;/code&gt; for &lt;code&gt;array&lt;/code&gt; &lt;em&gt;not&lt;/em&gt; to overlap with?&lt;/p&gt;

&lt;p&gt;It turns out that &lt;code&gt;restrict&lt;/code&gt; is more general than you might think.  What the &lt;code&gt;restrict&lt;/code&gt; in the modified &lt;code&gt;array_cleanup&lt;/code&gt; means is that, during its execution, the dynamic array pointed to by &lt;code&gt;array&lt;/code&gt; will not be modified by &lt;em&gt;any&lt;/em&gt; pointer &lt;em&gt;anywhere&lt;/em&gt; in the program, even if &lt;code&gt;free_fn&lt;/code&gt; has a copy of such a pointer.  Using &lt;code&gt;restrict&lt;/code&gt; is a promise you make to the compiler. (If you break that promise, even unintentionally, the result is &lt;a href="https://dev.to/pauljlucas/undefined-behavior-in-c-and-c-3a20"&gt;undefined behavior&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;restrict&lt;/code&gt;, the assembly becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.LBB0_4:
    mov  rdi, r12
    call r14                      ; (*free_fn)( element )
    add  r12, qword ptr [rbx + 8] ; element += array-&amp;gt;esize
    dec  r13                      ; --i
    jne  .LBB0_4                  ; i &amp;gt; 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The compiler has eliminated the &lt;code&gt;array-&amp;gt;len&lt;/code&gt; dereference and is now counting down to zero.&lt;/p&gt;

&lt;p&gt;But why didn’t the compiler optimize the remaining dereference (&lt;code&gt;qword ptr&lt;/code&gt;) for &lt;code&gt;esize&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;First, similar to &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;, &lt;code&gt;restrict&lt;/code&gt; &lt;em&gt;can&lt;/em&gt; be ignored by the compiler. Second, every CPU has only finite resources, most notably &lt;a href="https://en.wikipedia.org/wiki/Processor_register" rel="noopener noreferrer"&gt;registers&lt;/a&gt;.  In this case, the compiler presumably thought that the overall performance would still be better even if &lt;code&gt;esize&lt;/code&gt; were not put into a register.  If it were to be put into a register, then the compiler would have to ensure that it’s value is the same after &lt;code&gt;free_fn&lt;/code&gt; is called as before —&amp;nbsp;and presumably that was more costly than a dereference.&lt;/p&gt;

&lt;p&gt;As I noted in my &lt;code&gt;restrict&lt;/code&gt; article, &lt;code&gt;restrict&lt;/code&gt; isn’t yet part of standard C++; however, many compilers support &lt;a href="https://gcc.gnu.org/onlinedocs/gcc-14.2.0/gcc/Restricted-Pointers.html" rel="noopener noreferrer"&gt;&lt;code&gt;__restrict__&lt;/code&gt;&lt;/a&gt; as an extension.&lt;/p&gt;

&lt;h2&gt;
  
  
  Explicit Caching
&lt;/h2&gt;

&lt;p&gt;Of course you can forget about &lt;code&gt;restrict&lt;/code&gt; and just use local variables to cache the values as was done initially:&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;size_t&lt;/span&gt; &lt;span class="k"&gt;const&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;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="kt"&gt;size_t&lt;/span&gt; &lt;span class="k"&gt;const&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&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;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;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;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;Then, despite the function call in the loop, the assembly becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.LBB0_4:
    mov  rdi, rbx
    call r14      ; (*free_fn)( element )
    add  rbx, r13 ; element += esize
    dec  r15      ; --i
    jne  .LBB0_4  ; i &amp;gt; 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with no dereferences.&lt;/p&gt;

&lt;p&gt;In this case, the explicit use of local variables gave the compiler a “nudge” in what turns out to be the right direction for optimization. It’s entirely possible that the compiler could have decided to eliminate the local variables and return to doing a dereference if it concluded that was really better. But by using local variables, you’ve at least told the compiler that the dynamic array pointed to by &lt;code&gt;array&lt;/code&gt; will not be modified in the loop — you’ve given the compiler more information to make a better informed decision.&lt;/p&gt;

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

&lt;p&gt;If you want to optimize code using pointers, functions, and loops, consider using either &lt;code&gt;restrict&lt;/code&gt; or explicit caching. But you should always check the generated assembly to ensure your tuning is having the desired effect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Epilogue
&lt;/h2&gt;

&lt;p&gt;If you’ve never heard of the &lt;strong&gt;Compiler Explorer&lt;/strong&gt;, aka, &lt;a href="https://godbolt.org" rel="noopener noreferrer"&gt;&lt;code&gt;godbolt.org&lt;/code&gt;&lt;/a&gt;, it’s an extremly useful in-browser tool for compiling C or C++ code with virtually any compiler you’ve ever heard of, at any optimization level, and showing you a mapping from source lines to their corresponding assembly lines for most any CPU architecture.  (Why is it called godbolt? Because its creator is &lt;a href="https://www.linkedin.com/in/godbolt/" rel="noopener noreferrer"&gt;Matt Godbolt&lt;/a&gt;.)&lt;/p&gt;

</description>
      <category>c</category>
      <category>cpp</category>
    </item>
    <item>
      <title>Technical Writing Advice</title>
      <dc:creator>Paul J. Lucas</dc:creator>
      <pubDate>Thu, 18 Jun 2026 14:00:30 +0000</pubDate>
      <link>https://dev.to/pauljlucas/technical-writing-advice-28a6</link>
      <guid>https://dev.to/pauljlucas/technical-writing-advice-28a6</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I’ve occasionally thought about writing about how to write (and how &lt;em&gt;not&lt;/em&gt; to write) technical material.  Recently, someone e-mailed me asking for advice about doing just that.  So this article is a collection of my previous thoughts about this as well as a distillation of how I replied to that e-mail.&lt;/p&gt;

&lt;p&gt;Any kind of writing, like many other human endeavors, is a combination of &lt;em&gt;talent&lt;/em&gt; and &lt;em&gt;skill&lt;/em&gt;.  For talent, you’ve either got it or you don’t; whereas skill can be learned, improved, and mastered.  It’s generally difficult even to explain talent because it’s largely unconscious.  I can’t tell you &lt;em&gt;how&lt;/em&gt; the amorphous ideas in my head get converted to words on a page or screen — it just happens; however, I can tell you some things to do (and &lt;em&gt;not&lt;/em&gt; do).&lt;/p&gt;

&lt;p&gt;There are many kinds of technical material.  I’ve mostly written articles, journal papers, Unix-style manual pages, API documentation, and a couple of books, so my advice is relevant only for those.&lt;/p&gt;

&lt;p&gt;I largely consider the following advice to be &lt;em&gt;obvious&lt;/em&gt;, so I don’t think it &lt;em&gt;should&lt;/em&gt; be necessary; but I’ve seen lots of &lt;em&gt;bad&lt;/em&gt; technical writing, so I guess the advice is apparently necessary after all.&lt;/p&gt;

&lt;p&gt;The advice can be distilled into the following points.  Your writing should be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Different.&lt;/li&gt;
&lt;li&gt;Well-formatted.&lt;/li&gt;
&lt;li&gt;Right.&lt;/li&gt;
&lt;li&gt;Precise.&lt;/li&gt;
&lt;li&gt;Complete.&lt;/li&gt;
&lt;li&gt;Consistent.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also note that this advice is from the perspective of doing your &lt;em&gt;own&lt;/em&gt; technical writing, i.e., writing about what &lt;em&gt;you&lt;/em&gt; want to write about.  If you’re a technical writer by trade, then your day job is writing about what other people want you to write about.  You’re also most likely constrained by an in-house style guide.  My advice isn’t for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Different
&lt;/h2&gt;

&lt;p&gt;Before actually writing anything, you should first determine whether what you want to write about is worth writing at all. Does the world really need yet another introduction to basic data types like &lt;code&gt;int&lt;/code&gt; and &lt;code&gt;char&lt;/code&gt; in C?&lt;/p&gt;

&lt;p&gt;However, if you’re going to go &lt;em&gt;really&lt;/em&gt; deep into or show some obscure thing about or a creative use of a topic, i.e., something &lt;em&gt;different&lt;/em&gt;, then by all means go ahead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Formatting
&lt;/h2&gt;

&lt;p&gt;To me, it should be &lt;em&gt;obvious&lt;/em&gt; that what you write should be well-formatted — yet I’ve seen so many examples of badly formatted writing.  When badly formatted, reading becomes visually jarring and a chore to slog through. I don’t even understand how anyone can publish anything that’s badly formatted.  Don’t they look at it and think, “This looks terrible!”? (I suspect there’s a gene for having an aesthetic sense and some people don’t have it.)&lt;/p&gt;

&lt;p&gt;In contrast, in well-formatted writing, the formatting just fades into the background so that you don’t even notice it and reading becomes easy.&lt;/p&gt;

&lt;p&gt;For technical writing involving code, the code should be in a different typeface, generally &lt;a href="https://en.wikipedia.org/wiki/Monospaced_font" rel="noopener noreferrer"&gt;monospaced&lt;/a&gt;, and typically &lt;a href="https://en.wikipedia.org/wiki/Courier_(typeface)" rel="noopener noreferrer"&gt;Courier&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Typeface” is the correct term. A &lt;em&gt;typeface&lt;/em&gt; is a style of letters and symbols; a &lt;em&gt;font&lt;/em&gt; is a typeface in a particular size (e.g., 10 point) and style (e.g., bold). Courier, Helvetica, and Times Roman are typefaces; Helvetica 10 Bold is a font.&lt;/p&gt;

&lt;p&gt;I blame Apple for everyone’s mis-use of &lt;em&gt;font&lt;/em&gt; to mean &lt;em&gt;typeface&lt;/em&gt;.  Originally, the &lt;a href="https://en.wikipedia.org/wiki/Apple_Lisa" rel="noopener noreferrer"&gt;Lisa&lt;/a&gt; used &lt;a href="https://www.computerhistory.org/revolution/input-output/14/348/1864" rel="noopener noreferrer"&gt;&lt;strong&gt;Type Style&lt;/strong&gt;&lt;/a&gt; for the name of what is now the &lt;strong&gt;Font&lt;/strong&gt; menu in most GUI applications. But then for some reason, the &lt;a href="https://en.wikipedia.org/wiki/Mac_(computer)" rel="noopener noreferrer"&gt;Mac&lt;/a&gt; changed the menu name to &lt;strong&gt;Font&lt;/strong&gt; and the mis-use ensued.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If what you write is badly formatted, the rest pretty much doesn’t matter since nobody is going to want to read it anyway.&lt;/p&gt;

&lt;p&gt;Some things that form part of my (and others’) styles include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use inline or footnotes for incidental information or to cite sources. (Alternatively, you can use brackets like [42] or [Lucas, 1992] to cite sources with a References section.)&lt;/li&gt;
&lt;li&gt;Use parentheses for clarifying information or an aside that isn’t big enough to warrant either an inline or footnote.&lt;/li&gt;
&lt;li&gt;Use italics for one of emphasis, for the first occurrence of an important term, or the title of another work.&lt;/li&gt;
&lt;li&gt;Use quotes for one of literal text, a definition, a colloquial term, or a metaphor.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example that illustrates most of the above, here’s an excerpt from &lt;a href="https://link.springer.com/book/10.1007/979-8-8688-1597-3" rel="noopener noreferrer"&gt;Why Learn C&lt;/a&gt;, §1.1, p. 3:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;C program source files conventionally end with a “&lt;code&gt;.c&lt;/code&gt;” extension, so, assuming this program is in a file &lt;code&gt;hello.c&lt;/code&gt;, it must be &lt;em&gt;compiled&lt;/em&gt; (converted from source code into an executable) with a &lt;em&gt;C compiler&lt;/em&gt;. On most Unix systems, the C compiler is named “&lt;code&gt;cc&lt;/code&gt;” (short for “C compiler”). &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Be Right
&lt;/h2&gt;

&lt;p&gt;It should also be &lt;em&gt;obvious&lt;/em&gt; that what you write should be right — yet I’ve seen so many examples of what someone has written is flat out &lt;em&gt;wrong&lt;/em&gt;.  Even if you think you know something well, double check before you write about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Be Precise
&lt;/h2&gt;

&lt;p&gt;While I think all writing should be precise, technical writing especially needs to be precise.  Some examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Parameters and arguments are different things.&lt;/li&gt;
&lt;li&gt;If something must be true, then use “must.”  (See also &lt;a href="https://www.rfc-editor.org/info/rfc2119/" rel="noopener noreferrer"&gt;RFC 2119&lt;/a&gt;.)&lt;/li&gt;
&lt;li&gt;Use “only if” whenever possible.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For an example of “only if,” consider:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The standard library function &lt;code&gt;isprint&lt;/code&gt; returns true if a character is “printable,” that is one of a space, a punctuation symbol, a letter, or a digit.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The problem with just using “if” is that it incorrectly leaves open the possibility that &lt;code&gt;isprint&lt;/code&gt; returns true in other cases as well. Replacing “if” with “only if” correctly eliminates that possibility.  As a rule of thumb, any time you use “if” in a sentence, try replacing it with “only if”: if the sentence still sounds right and is more correct, then use “only if.”&lt;/p&gt;

&lt;h2&gt;
  
  
  Be Complete
&lt;/h2&gt;

&lt;p&gt;Don’t write something that’s either only partly true or mostly true. The situation you want to avoid is a reader reading something you’ve written and thinking that’s &lt;em&gt;all&lt;/em&gt; there is to the topic.&lt;/p&gt;

&lt;p&gt;Yes, I understand that you may not want to wade deep into the weeds in an introduction for a topic.  If that’s the case, at least mention that there’s more to a topic that you’ll get to later or can safely be ignored for now. For example, &lt;a href="https://link.springer.com/book/10.1007/979-8-8688-1597-3" rel="noopener noreferrer"&gt;Why Learn C&lt;/a&gt;, §1.5, p. 14, contains the sentence:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Before continuing the tour, we need to digress on computer memory. It’s basically a (very long) sequence of bytes, each having a unique integer address.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;While that’s true, it’s only &lt;em&gt;mostly&lt;/em&gt; true; but then it’s followed by the inline note:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;■ This is an oversimplification due to both register and cache memory, but those can be safely ignored for now. □&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Be Consistent
&lt;/h2&gt;

&lt;p&gt;Be consistent about word choices and term use.  For example, if you use “error code,” don’t later write “status code.”  Readers may wonder if they’re the same thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Note on AI
&lt;/h2&gt;

&lt;p&gt;Don’t use AI to do the majority (or all) of your writing, certainly don’t copy &amp;amp; paste verbatim from it.  Sometimes I use AI like a thesaurus to suggest alternate words or terms, but that’s pretty much it for me.&lt;/p&gt;

&lt;p&gt;If you’re writing but not fluent in a language that is not your native language, you can be forgiven for using AI a bit more, e.g., copying something you’ve written into an AI and asking it for advice.  Still, don’t copy its suggestions verbatim: edit them to fit into the rest of your writing style.&lt;/p&gt;

&lt;h2&gt;
  
  
  Things to Not Do
&lt;/h2&gt;

&lt;p&gt;Here’s a non-exhaustive list of things that, when I see them, don’t give me confidence that the rest of what I’m about to read will be worth my time.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Unless you’re writing a personal account of something or giving a personal opinion, don’t write in first-person (“I ...”).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Don’t include gratuitous images. Include images only that illustrate what you’re trying to explain. Gratuitous images are distracting. Even worse are animated images. You don’t want what you write to look gaudy.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For titles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Don’t use numbers of things (unless there’s some importance to the numbers).&lt;/li&gt;
&lt;li&gt;Don’t use hyperbole.&lt;/li&gt;
&lt;li&gt;Don’t use click-bait wording.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It makes your writing sound juvenile. Here’s an actual bad example I recently found online:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;7 Coding Patterns I Stole From Senior Engineers&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Who cares if it’s seven? Or five? Or ten? “Stole?” It’s called &lt;em&gt;learning from&lt;/em&gt; — presumably from open source that’s, well, open and free to learn and copy from.  Better:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Coding Patterns Used by Senior Engineers&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Or something like that.&lt;/p&gt;

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

&lt;p&gt;To adapt a some advice one of my mentors gave to me once: do you want people to remember your writing for the way it looked or for what it said?&lt;/p&gt;

&lt;p&gt;If you want to be taken seriously, then write as if you were submitting your writing to a prestigious journal or publisher.  Some day, you might want to.&lt;/p&gt;

</description>
      <category>documentation</category>
      <category>technical</category>
      <category>writing</category>
    </item>
    <item>
      <title>Clifford’s (aka, Claire’s) Device in C and C++</title>
      <dc:creator>Paul J. Lucas</dc:creator>
      <pubDate>Wed, 10 Jun 2026 23:29:18 +0000</pubDate>
      <link>https://dev.to/pauljlucas/cliffords-aka-claires-device-in-c-and-c-2p33</link>
      <guid>https://dev.to/pauljlucas/cliffords-aka-claires-device-in-c-and-c-2p33</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;If you’ve been programming in C or C++ for a while, you likely have heard of &lt;a href="https://en.wikipedia.org/wiki/Duff%27s_device" rel="noopener noreferrer"&gt;Duff’s Device&lt;/a&gt; that takes advantage of C’s often-derided “feature” where &lt;code&gt;case&lt;/code&gt; blocks “fall through” into the next case (if any).&lt;/p&gt;

&lt;p&gt;Regardless of what you think of that, I only recently discovered that there’s another “device” known as &lt;a href="https://clifford.at/cliffords-device.html" rel="noopener noreferrer"&gt;&lt;em&gt;Clifford’s Device&lt;/em&gt;&lt;/a&gt; (&lt;a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3355.htm" rel="noopener noreferrer"&gt;alternatively known&lt;/a&gt; as &lt;em&gt;Claire’s Device&lt;/em&gt;).  While the problem it solves is completely different from Duff’s, it uses another of C’s quirks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preamble
&lt;/h2&gt;

&lt;p&gt;Sometimes you have a block of code that you want to delete temporarily, but don’t want to delete it permanently just in case you might need it again in the future.&lt;/p&gt;

&lt;p&gt;If you’re using a &lt;a href="https://en.wikipedia.org/wiki/Version_control" rel="noopener noreferrer"&gt;VCS&lt;/a&gt; like &lt;a href="https://en.wikipedia.org/wiki/Git" rel="noopener noreferrer"&gt;git&lt;/a&gt;, of course you &lt;em&gt;can&lt;/em&gt; delete the code because it’ll be preserved in the history, but, if you want the code back, you have to find the commit that deleted it and revert the commit.  If the commit did more than simply delete the relevant code, then it gets harder.&lt;/p&gt;

&lt;p&gt;As an alternative, you can use the preprocessor to disable a block of code:&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="c"&gt;#if 0
  // ... disabled block of code ...
#endif
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As another alternative, you can 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="k"&gt;if&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="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ... disabled block of code ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since &lt;code&gt;0&lt;/code&gt; is always false, the code, though compiled, will never be executed.  (The optimizer might even optimize the code away entirely.)&lt;/p&gt;

&lt;h2&gt;
  
  
  The Device
&lt;/h2&gt;

&lt;p&gt;The device also uses &lt;code&gt;if (0)&lt;/code&gt; and is trivial: you simply include a label that’s the target of a &lt;a href="https://dev.to/pauljlucas/goto-in-c-and-c-9gc"&gt;&lt;code&gt;goto&lt;/code&gt;&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="k"&gt;if&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="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;label:&lt;/span&gt;
    &lt;span class="c1"&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;That’s it.  What use is that?  It allows a block of code to be executed only if explicitly &lt;code&gt;goto&lt;/code&gt;d.  Code before it won’t simply “fall into” it. The code also resumes the normal code flow.&lt;/p&gt;

&lt;p&gt;We can rewrite the &lt;code&gt;missing_arg&lt;/code&gt; example from the &lt;a href="https://dev.to/pauljlucas/goto-in-c-and-c-9gc"&gt;&lt;code&gt;goto&lt;/code&gt;&lt;/a&gt; post to use the device:&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;cli_options_init&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="n"&gt;pargc&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;pargv&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;// ...&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="c1"&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;option&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;has_arg&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;required_argument&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;optarg&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;goto&lt;/span&gt; &lt;span class="n"&gt;missing_arg&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;SKIP_WS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;optarg&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;optarg&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="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;'\0'&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="k"&gt;goto&lt;/span&gt; &lt;span class="n"&gt;missing_arg&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;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;opt&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;span class="k"&gt;case&lt;/span&gt; &lt;span class="sc"&gt;':'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;goto&lt;/span&gt; &lt;span class="n"&gt;missing_arg&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;// ...&lt;/span&gt;
  &lt;span class="c1"&gt;//return;   // This return is no longer needed&lt;/span&gt;

  &lt;span class="k"&gt;if&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="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;missing_arg:&lt;/span&gt;
    &lt;span class="n"&gt;fatal_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;EX_USAGE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;%s&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt; requires an argument&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="n"&gt;get_opt_format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;opt&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;':'&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;optopt&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;opt&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;While the device works as-is, it’s a bit ugly.  As it often the case, we can use a preprocessor &lt;a href="https://dev.to/pauljlucas/cc-preprocessor-macros-fh5"&gt;macro&lt;/a&gt; to hide the ugliness:&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 only_if(LABEL)   if (0) LABEL:
&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="n"&gt;only_if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;missing_arg&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fatal_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;EX_USAGE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;%s&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt; requires an argument&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="n"&gt;get_opt_format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;opt&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;':'&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;optopt&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;opt&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;The “only if” means that the code will be executed &lt;em&gt;only if&lt;/em&gt; an option is missing its required argument.&lt;/p&gt;

&lt;p&gt;Notice that the position of the label is now &lt;em&gt;before&lt;/em&gt; the &lt;code&gt;{&lt;/code&gt;.  It’s completely equivalent because a compound statement of &lt;code&gt;{&lt;/code&gt; ... &lt;code&gt;}&lt;/code&gt; &lt;em&gt;is&lt;/em&gt; a statement and C allows you to put a label before any statement.&lt;/p&gt;

&lt;p&gt;You could even take macros a step further and simulate exception handling in C:&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 try           if (1)
#define throw         goto
#define catch(LABEL)  if (0) LABEL:
&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;cli_options_init&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="n"&gt;pargc&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;pargv&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;// ...&lt;/span&gt;
  &lt;span class="n"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&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;option&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;has_arg&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;required_argument&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;optarg&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;throw&lt;/span&gt; &lt;span class="n"&gt;missing_arg&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;SKIP_WS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;optarg&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;optarg&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="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;'\0'&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="n"&gt;throw&lt;/span&gt; &lt;span class="n"&gt;missing_arg&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;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;missing_arg&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fatal_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;EX_USAGE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;%s&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt; requires an argument&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="n"&gt;get_opt_format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;opt&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;':'&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;optopt&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;opt&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course this is a false facade since this “exception handling” works only within the &lt;em&gt;same&lt;/em&gt; function unlike real exception handling where an exception can be caught in &lt;em&gt;any&lt;/em&gt; calling function.&lt;/p&gt;

&lt;p&gt;Should you actually do this in production code?  Probably not.  I only wanted to show that the device &lt;em&gt;can&lt;/em&gt; be used in a “clever” (revolting?) way for curiosity.  Besides, there is a &lt;a href="https://dev.to/pauljlucas/setjmp-longjmp-and-exception-handling-in-c-1h7h"&gt;better way to do exception handling in C&lt;/a&gt;.  In C++, you have real exception handling, of course.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;switch&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;You can also use the device in &lt;code&gt;switch&lt;/code&gt; statements just like Duff’s:&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;switch&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="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;only_if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="sc"&gt;'\0'&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="err"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;only_if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="sc"&gt;'='&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="err"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;only_if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Doing so allows you to eliminate the &lt;code&gt;break&lt;/code&gt;s between &lt;code&gt;case&lt;/code&gt;s.  This works because a &lt;code&gt;case&lt;/code&gt; or &lt;code&gt;default&lt;/code&gt; label &lt;em&gt;is&lt;/em&gt; a label syntactically.&lt;/p&gt;

&lt;p&gt;Should you actually do this in production code?  Probably not.  Even if you dislike that C “falls through” into the next &lt;code&gt;case&lt;/code&gt;, code using such a macro is likely more confusing for the uninitiated than C’s normal and well-known behavior.  I only wanted to show that the device &lt;em&gt;can&lt;/em&gt; be used in a &lt;code&gt;switch&lt;/code&gt; for curiosity.&lt;/p&gt;

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

&lt;p&gt;Clifford’s (or Claire’s) Device is another quirky “feature” of C in that you can &lt;code&gt;goto&lt;/code&gt; &lt;em&gt;into&lt;/em&gt; a compound statement at any point.  It has a marginal use when used with a &lt;code&gt;goto&lt;/code&gt;; less so with &lt;code&gt;switch&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Use wisely.&lt;/p&gt;

</description>
      <category>c</category>
      <category>cpp</category>
    </item>
    <item>
      <title>goto in C and C++</title>
      <dc:creator>Paul J. Lucas</dc:creator>
      <pubDate>Mon, 08 Jun 2026 17:48:01 +0000</pubDate>
      <link>https://dev.to/pauljlucas/goto-in-c-and-c-9gc</link>
      <guid>https://dev.to/pauljlucas/goto-in-c-and-c-9gc</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Both &lt;a href="https://www.cppreference.com/c/language/goto" rel="noopener noreferrer"&gt;C&lt;/a&gt; and &lt;a href="https://www.cppreference.com/cpp/language/goto" rel="noopener noreferrer"&gt;C++&lt;/a&gt; include the &lt;a href="https://en.wikipedia.org/wiki/Goto" rel="noopener noreferrer"&gt;&lt;code&gt;goto&lt;/code&gt;&lt;/a&gt; statement that goes (jumps) to the statement having the given label within the same function, 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;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;disaster&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;goto&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;

&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;// handle the error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you probably know, &lt;code&gt;goto&lt;/code&gt; has a bad reputation stemming chiefly from &lt;a href="https://en.wikipedia.org/wiki/Edsger_W._Dijkstra" rel="noopener noreferrer"&gt;Edsger Dijkstra&lt;/a&gt;’s infamous &lt;a href="https://dl.acm.org/doi/10.1145/362929.362947" rel="noopener noreferrer"&gt;go to Statement Considered Harmful&lt;/a&gt; (1968) letter wherein he wrote in part:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For a number of years I have been familiar with the observation that the quality of programmers is a decreasing function of the density of &lt;strong&gt;go to&lt;/strong&gt; statements in the programs they produce. More recently I discovered why the use of the &lt;strong&gt;go to&lt;/strong&gt; statement has such disastrous effects, and I became convinced that the &lt;strong&gt;go to&lt;/strong&gt; statement should be abolished from all “higher level” programming languages ….&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Notice that he says the quality of &lt;strong&gt;&lt;em&gt;programmers&lt;/em&gt;&lt;/strong&gt;, not &lt;strong&gt;&lt;em&gt;programs&lt;/em&gt;&lt;/strong&gt;, decreases the denser the use of &lt;code&gt;goto&lt;/code&gt; is; hence not only are programs with lots of &lt;code&gt;goto&lt;/code&gt;s bad programs, but if you’re the author of such a program, you’re a &lt;strong&gt;&lt;em&gt;bad programmer&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Not only was Dijkstra’s letter extremely influential, but its title has spurred an entire &lt;a href="https://en.wikipedia.org/wiki/Considered_harmful" rel="noopener noreferrer"&gt;considered harmful&lt;/a&gt; template for other essays and papers including &lt;a href="https://meyerweb.com/eric/comment/chech.html" rel="noopener noreferrer"&gt;“Considered Harmful” Essays Considered Harmful&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As a curious historical note, Dijkstra’s original title was “A Case Against the Goto Statement,” but it was &lt;a href="https://en.wikipedia.org/wiki/Niklaus_Wirth" rel="noopener noreferrer"&gt;Niklaus Wirth&lt;/a&gt;, the then-editor of &lt;a href="https://en.wikipedia.org/wiki/Communications_of_the_ACM" rel="noopener noreferrer"&gt;CACM&lt;/a&gt;, that changed the title.  We’ll never know if Dijkstra’s letter would have had the same degree of influence had it kept its original title, but probably.&lt;/p&gt;

&lt;p&gt;For a detailed analysis of Dijkstra’s letter, see &lt;a href="http://david.tribble.com/text/goto.html" rel="noopener noreferrer"&gt;Dijkstra’s Letter, Annotated&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What led to Dijkstra writing his letter was the (over)use of &lt;code&gt;goto&lt;/code&gt; in programs written in either early versions of &lt;a href="https://en.wikipedia.org/wiki/Fortran" rel="noopener noreferrer"&gt;Fortran&lt;/a&gt; (1957–1966) and &lt;a href="https://en.wikipedia.org/wiki/BASIC" rel="noopener noreferrer"&gt;BASIC&lt;/a&gt; (1964–).  To be fair, those programming languages had no other way to jump elsewhere in a program which is in part what led to increased support for the &lt;a href="https://en.wikipedia.org/wiki/Structured_programming" rel="noopener noreferrer"&gt;structured programming&lt;/a&gt; movement. (The term “structured programming” was coined by Dijkstra.)&lt;/p&gt;

&lt;p&gt;Even &lt;a href="https://en.wikipedia.org/wiki/Brian_Kernighan" rel="noopener noreferrer"&gt;Kernighan&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/Dennis_Ritchie" rel="noopener noreferrer"&gt;Ritchie&lt;/a&gt; in their also extremely influential &lt;a href="https://en.wikipedia.org/wiki/The_C_Programming_Language" rel="noopener noreferrer"&gt;The C Programming Language&lt;/a&gt; wrote in part (1st ed., §3.9, pp. 62–63):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;C provides the infinitely-abusable &lt;code&gt;goto&lt;/code&gt; statement, and labels to branch to. Formally, the &lt;code&gt;goto&lt;/code&gt; is never necessary, and in practice it is almost always easy to write code without it. We have not used &lt;code&gt;goto&lt;/code&gt; in this book. Nonetheless, we will suggest a few situations where &lt;code&gt;goto&lt;/code&gt;s may find a place.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Those few situations are what this post is about.&lt;/p&gt;

&lt;h2&gt;
  
  
  Legitimate Uses
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Aborting Processing
&lt;/h3&gt;

&lt;p&gt;One legitimate use for &lt;code&gt;goto&lt;/code&gt; was shown at the outset of this post, namely error handling, but where either clean-up code is necessary, such as &lt;a href="https://www.cppreference.com/c/memory/free" rel="noopener noreferrer"&gt;freeing&lt;/a&gt; memory, &lt;a href="https://www.cppreference.com/c/io/fclose" rel="noopener noreferrer"&gt;closing&lt;/a&gt; files, or &lt;a href="https://www.cppreference.com/c/thread/mtx_unlock" rel="noopener noreferrer"&gt;unlocking&lt;/a&gt; mutexes, or simply printing the same error message.  The legitimacy increases with the number of &lt;code&gt;goto&lt;/code&gt;s going to the same label.&lt;/p&gt;

&lt;p&gt;For example, &lt;a href="https://github.com/paul-j-lucas/include-tidy/blob/412c75d5d4c6b4e0759244b1d2c3072f806883f1/src/cli_options.c#L891" rel="noopener noreferrer"&gt;this&lt;/a&gt; code from 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 contains:&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;cli_options_init&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="n"&gt;pargc&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;pargv&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;// ...&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="c1"&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;option&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;has_arg&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;required_argument&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;optarg&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;goto&lt;/span&gt; &lt;span class="n"&gt;missing_arg&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;SKIP_WS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;optarg&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;optarg&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="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;'\0'&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="k"&gt;goto&lt;/span&gt; &lt;span class="n"&gt;missing_arg&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;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;opt&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;span class="k"&gt;case&lt;/span&gt; &lt;span class="sc"&gt;':'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;goto&lt;/span&gt; &lt;span class="n"&gt;missing_arg&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;// ...&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nl"&gt;missing_arg:&lt;/span&gt;
  &lt;span class="n"&gt;fatal_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;EX_USAGE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;%s&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt; requires an argument&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="n"&gt;get_opt_format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;opt&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;':'&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;optopt&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;opt&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 it is possible to eliminate the uses of &lt;code&gt;goto&lt;/code&gt; here, doing so would require either much more deeply nested &lt;code&gt;if&lt;/code&gt; statements or the introduction of flags, both of which would make the code harder to understand.&lt;/p&gt;

&lt;p&gt;For a case where you have to do specific clean-up, such as calling &lt;code&gt;free&lt;/code&gt;, a &lt;a href="https://gobyexample.com/defer" rel="noopener noreferrer"&gt;&lt;code&gt;defer&lt;/code&gt;&lt;/a&gt; statement like the one found in Go would be better if it were added to C:&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;read_file&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;file&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="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;buf&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="n"&gt;BUF_SIZE&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;defer&lt;/span&gt; &lt;span class="nf"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// hypothetical defer in C&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, no matter&lt;sup&gt;*&lt;/sup&gt; how you return from the function, &lt;code&gt;free&lt;/code&gt; will be called.&lt;/p&gt;

&lt;p&gt;There actually is a &lt;a href="https://www.open-std.org/JTC1/SC22/WG14/www/docs/n3434.htm" rel="noopener noreferrer"&gt;proposal&lt;/a&gt; to add &lt;code&gt;defer&lt;/code&gt; to C.  Currently, it’s slated to be added to &lt;a href="https://en.wikipedia.org/wiki/C29_(C_standard_revision)" rel="noopener noreferrer"&gt;C29&lt;/a&gt;, the next standard version of C.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;* Well, there are cases where it does matter, but that would be going too far into the weeds on &lt;code&gt;defer&lt;/code&gt; that this post isn’t about.  For such details, read the proposal.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In C++, there are destructors, so this use for &lt;code&gt;goto&lt;/code&gt; is largely eliminated.&lt;/p&gt;

&lt;h3&gt;
  
  
  Nested Loop or &lt;code&gt;switch&lt;/code&gt; Statements
&lt;/h3&gt;

&lt;p&gt;While both C and C++ contain the &lt;a href="https://www.cppreference.com/c/language/break" rel="noopener noreferrer"&gt;&lt;code&gt;break&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://www.cppreference.com/c/language/continue" rel="noopener noreferrer"&gt;&lt;code&gt;continue&lt;/code&gt;&lt;/a&gt; statements, &lt;code&gt;break&lt;/code&gt; breaks out of only the most lexically enclosing loop (&lt;code&gt;while&lt;/code&gt;, &lt;code&gt;do&lt;/code&gt;, or &lt;code&gt;for&lt;/code&gt;) or &lt;code&gt;switch&lt;/code&gt;; &lt;code&gt;continue&lt;/code&gt; continues only the most lexically enclosing loop. There’s also &lt;a href="https://thephd.dev/c2y-the-defer-technical-specification-its-time-go-go-go" rel="noopener noreferrer"&gt;this&lt;/a&gt; article that’s good.&lt;/p&gt;

&lt;p&gt;In some cases, however, you want either to &lt;code&gt;break&lt;/code&gt; or &lt;code&gt;continue&lt;/code&gt; the &lt;em&gt;not&lt;/em&gt; most lexically enclosing loop or &lt;code&gt;switch&lt;/code&gt;.  Unlike in either Java or Rust, in C or C++, you can only use a &lt;code&gt;goto&lt;/code&gt;.  The example already given above is also an example for this case.&lt;/p&gt;

&lt;p&gt;There is also a &lt;a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3355.htm" rel="noopener noreferrer"&gt;proposal&lt;/a&gt; to add named loops to C such that you could do 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="nl"&gt;loop:&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;int&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;j&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;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;span class="k"&gt;case&lt;/span&gt; &lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// hypothetical named loop&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, a label in front of a loop can be referenced by a &lt;code&gt;break&lt;/code&gt; or &lt;code&gt;continue&lt;/code&gt; in addition to &lt;code&gt;goto&lt;/code&gt;. Currently, it too is slated to be added to C29.&lt;/p&gt;

&lt;h2&gt;
  
  
  Restrictions
&lt;/h2&gt;

&lt;p&gt;Prior to &lt;a href="https://en.wikipedia.org/wiki/C23_(C_standard_revision)" rel="noopener noreferrer"&gt;C23&lt;/a&gt;, a label could &lt;em&gt;not&lt;/em&gt; be attached to a declaration (because a declaration is not a statement in C; it is in C++):&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;disaster&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;goto&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;           &lt;span class="c1"&gt;// illegal &amp;lt; C23; OK in C23 or C++&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;err_code&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The common work-around is to insert a null statement, i.e., a single semicolon:&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="p"&gt;;&lt;/span&gt;          &lt;span class="c1"&gt;// note ';' -- OK in all C versions&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;err_code&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All C versions forbid jumping past the declaration of a “variably modified type,” i.e., variable length arrays (VLAs) or pointers to such:&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="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="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="k"&gt;goto&lt;/span&gt; &lt;span class="n"&gt;skip&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;     &lt;span class="c1"&gt;// error: can't skip past ...&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&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="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;      &lt;span class="c1"&gt;// ... VLA&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;(&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="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;   &lt;span class="c1"&gt;// ... or pointer to VLA&lt;/span&gt;

&lt;span class="nl"&gt;skip:&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;C++ has more restrictions than C regarding use of &lt;code&gt;goto&lt;/code&gt;, specifically that you can’t jump past a declaration if its type has a “non-trivial constructor” or has an initializer:&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;goto&lt;/span&gt; &lt;span class="n"&gt;skip&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&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="c1"&gt;// OK: no initializer&lt;/span&gt;
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// error: has non-trivial constructor&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y&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;span class="c1"&gt;// error: has initializer&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="n"&gt;skip&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Advice
&lt;/h2&gt;

&lt;p&gt;Here’s some advice for using (or not using) &lt;code&gt;goto&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Of course prefer &lt;code&gt;break&lt;/code&gt;, &lt;code&gt;continue&lt;/code&gt;, &lt;code&gt;return&lt;/code&gt;, or any loop when those do exactly what you want.&lt;/li&gt;
&lt;li&gt;If you would need to add one of multiple flags, multiple tests, or more deeply nested code, consider a &lt;code&gt;goto&lt;/code&gt; instead.&lt;/li&gt;
&lt;li&gt;Personally, I think it’s a good practice only to go to a line that’s &lt;em&gt;later&lt;/em&gt; in a function rather than earlier, either immediately after a loop or at the end of a function.  If you want to go earlier, it likely means you’re looping, so use an actual loop instead.&lt;/li&gt;
&lt;li&gt;Put clean-up code that’s the target of a &lt;code&gt;goto&lt;/code&gt; at the end of a function where it more clearly stands out.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;I think Dijkstra’s wish to abolish &lt;code&gt;goto&lt;/code&gt; entirely goes a bit far.  Certainly, you want to avoid either inappropriate or over-use of &lt;code&gt;goto&lt;/code&gt;s lest you end up with &lt;a href="https://en.wikipedia.org/wiki/Spaghetti_code" rel="noopener noreferrer"&gt;spaghetti code&lt;/a&gt;.  While a lot of code can (and should) be written easily without &lt;code&gt;goto&lt;/code&gt;, a justified use of an occasional one won’t make you a bad programmer.&lt;/p&gt;

</description>
      <category>c</category>
      <category>cpp</category>
    </item>
    <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;ia&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;ia&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 &lt;code&gt;void*&lt;/code&gt; 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;ia&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;ia&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;ia&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;ia&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;ia&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;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;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;ia&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>
  </channel>
</rss>
