<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://jorenar.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://jorenar.com/" rel="alternate" type="text/html" /><updated>2026-08-22T21:57:28+00:00</updated><id>https://jorenar.com/feed.xml</id><title type="html">Jorenar</title><author><name>Jorenar</name></author><entry><title type="html">My art supplies</title><link href="https://jorenar.com/my-art-supplies" rel="alternate" type="text/html" title="My art supplies" /><published>2026-08-22T00:00:00+00:00</published><updated>2026-08-22T00:00:00+00:00</updated><id>https://jorenar.com/my-art-supplies</id><content type="html" xml:base="https://jorenar.com/my-art-supplies"><![CDATA[<h2 id="mechanical-pencils">Mechanical pencils</h2>

<ul>
  <li>Derwent Precision 0.5mm</li>
  <li>Faber-Castell TK-FINE 9715</li>
  <li>Koh-I-Noor 5347</li>
  <li>Koh-I-Noor 5900</li>
  <li>KOS-01-KŁ</li>
  <li>Pentel P205</li>
  <li>Pilot H225</li>
</ul>

<h2 id="nib-holders">Nib holders</h2>

<ul>
  <li><a href="https://web.archive.org/web/20130526114610/http://www.sunho-art.com/chinese/tool/201317.htm">Sunho Art 漫画笔杆B</a></li>
</ul>

<h2 id="erasers">Erasers</h2>

<ul>
  <li>Faber-Castell kneadable eraser</li>
  <li><a href="https://www.action.com/pl-pl/p/3223678">Karsten Crafts&amp;Co electric eraser</a></li>
  <li>Koh-I-Noor Eraser Pencil 6312</li>
  <li>Staedtler Rasoplast (black)</li>
  <li>Tombow MONO zero</li>
</ul>

<h2 id="inks">Inks</h2>

<ul>
  <li>Astra Artea (black)</li>
  <li>Astra Artea (karmin)</li>
  <li>Parker Quink (black)</li>
  <li>Koh-I-Noor 1417010</li>
  <li><em>generic printer refills</em></li>
</ul>

<h2 id="inkwells">Inkwells</h2>

<ul>
  <li><em>20ml bottle with aluminium cap</em></li>
  <li><em>mini tomato paste jar</em></li>
</ul>

<h2 id="pencil-cases">Pencil cases</h2>

<ul>
  <li>Koh-I-Noor Rollo DJTB-24</li>
  <li>Kalnex F9</li>
</ul>

<h2 id="brush-pens">Brush pens</h2>

<ul>
  <li>Kuretake RB-6000AT-010</li>
</ul>

<h2 id="sharpeners">Sharpeners</h2>

<ul>
  <li>Faber-Castell 184100</li>
  <li><em>generic sharpener</em></li>
</ul>

<h2 id="gloves">Gloves</h2>

<ul>
  <li><a href="https://aliexpress.com/item/1005005900912248.html">Bview 2-finger/3-layer</a></li>
</ul>

<h2 id="sketchbooks">Sketchbooks</h2>

<ul>
  <li>Canson ArtBook One (10.2 x 15.2 cm)</li>
  <li>Artmate Field Sketch Pad HSB-A4</li>
</ul>

<h2 id="tablets">Tablets</h2>

<ul>
  <li>One by Wacom M</li>
</ul>]]></content><author><name>Jorenar</name></author><summary type="html"><![CDATA[Mechanical pencils]]></summary></entry><entry><title type="html">Retrieving array length across languages</title><link href="https://jorenar.com/arrlen-across-langs" rel="alternate" type="text/html" title="Retrieving array length across languages" /><published>2024-12-26T00:00:00+00:00</published><updated>2024-12-26T00:00:00+00:00</updated><id>https://jorenar.com/arrlen-across-langs</id><content type="html" xml:base="https://jorenar.com/arrlen-across-langs"><![CDATA[<style>
  .langs-list {
    column-count: 3;
  }
  @media only screen and (max-width: 700px) {
    .langs-list {
      column-count: 2;
    }
  }
  @media only screen and (max-width: 500px) {
    .langs-list {
      column-count: 1;
    }
  }
</style>

<p>The upcoming revision of the C language standard (for now called C2y) is
about to feature a new operator that essentially is a standardization of
ages old <code>sizeof arr / sizeof arr[0]</code> trick for getting number of elements
in an array. But as we all know, beside cache invalidation, and off-by-one
errors, the 2nd hard problem in Computer Science is naming things.</p>

<p>Initially it was supposed to be just a quick e-mail during the discussion
with just few examples, but as I've gone into the rabbit hole, it somehow
ended in a white paper format. You can read that version on the WG14 website
as document <a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3402.pdf">N3402</a>.</p>

<p>I'm fairly sure over 100 languages listed in the "official" document is good
enough sample size of a prior art to decide upon good name for C language,
thus to not spam the committee further, any updates and additions I'll list
here, in this blogpost copy of the paper.</p>

<p>Enjoy!</p>

<ul id="markdown-toc">
  <li><a href="#popular-high-level-computer-languages" id="markdown-toc-popular-high-level-computer-languages">Popular high-level computer languages</a></li>
  <li><a href="#getting-length-of-array-like-objects" id="markdown-toc-getting-length-of-array-like-objects">Getting length of array-like objects</a>    <ul>
      <li><a href="#languages-using-size" id="markdown-toc-languages-using-size">Languages using "size"</a></li>
      <li><a href="#languages-using-length" id="markdown-toc-languages-using-length">Languages using "length"</a></li>
      <li><a href="#languages-using-count" id="markdown-toc-languages-using-count">Languages using "count"</a></li>
      <li><a href="#languages-using-other-words" id="markdown-toc-languages-using-other-words">Languages using other words</a></li>
      <li><a href="#languages-using-symbols" id="markdown-toc-languages-using-symbols">Languages using symbols</a></li>
      <li><a href="#languages-where-length-is-computed" id="markdown-toc-languages-where-length-is-computed">Languages where length is computed</a></li>
      <li><a href="#languages-where-arrays-are-implemented-by-users" id="markdown-toc-languages-where-arrays-are-implemented-by-users">Languages where arrays are implemented by users</a></li>
    </ul>
  </li>
  <li><a href="#observations" id="markdown-toc-observations">Observations</a></li>
</ul>

<h2 id="popular-high-level-computer-languages">Popular high-level computer languages</h2>

<ul class="langs-list">
  <li>Ada</li>
  <li>ABAP</li>
  <li>ALGOL</li>
  <li>Apex</li>
  <li>APL</li>
  <li>AWK
    <ul>
      <li>gawk</li>
    </ul>
  </li>
  <li>BASIC</li>
  <li>Batch files</li>
  <li>C</li>
  <li>C Shell</li>
  <li>C#</li>
  <li>C++</li>
  <li>CHILL</li>
  <li>CLIPS</li>
  <li>CMake</li>
  <li>COBOL</li>
  <li>Cobra</li>
  <li>ColdFusion</li>
  <li>Crystal</li>
  <li>Curl</li>
  <li>D</li>
  <li>Dart</li>
  <li>ECMAScript
    <ul>
      <li>ActionScript</li>
      <li>JavaScript
        <ul>
          <li>CoffeeScript</li>
          <li>JScript</li>
          <li>TypeScript</li>
        </ul>
      </li>
    </ul>
  </li>
  <li>Elixir</li>
  <li>Elm</li>
  <li>Erlang</li>
  <li>Forth</li>
  <li>Fortran</li>
  <li>FoxPro</li>
  <li>GAMS</li>
  <li>GDScript</li>
  <li>GLSL</li>
  <li>Go</li>
  <li>Groovy</li>
  <li>Hack</li>
  <li>Haskell</li>
  <li>Icon</li>
  <li>Java</li>
  <li>Julia</li>
  <li>Kotlin</li>
  <li>LabVIEW</li>
  <li>Lisp
    <ul>
      <li>Clojure</li>
      <li>Common Lisp</li>
      <li>Emacs Lisp</li>
      <li>Racket</li>
      <li>Scheme</li>
    </ul>
  </li>
  <li>Logo</li>
  <li>Lua</li>
  <li>Makefile
    <ul>
      <li>GNU Make</li>
    </ul>
  </li>
  <li>Maple</li>
  <li>MATLAB</li>
  <li>Modula-2</li>
  <li>Modula-3</li>
  <li>Mojo</li>
  <li>ML
    <ul>
      <li>F#</li>
      <li>OCaml</li>
      <li>Standard ML</li>
    </ul>
  </li>
  <li>MQL5</li>
  <li>Nim</li>
  <li>occam 2</li>
  <li>Objective-C</li>
  <li>Odin</li>
  <li>Pascal
    <ul>
      <li>Delphi</li>
      <li>Object Pascal</li>
    </ul>
  </li>
  <li>Perl</li>
  <li>PHP</li>
  <li>PL/I</li>
  <li>PostScript</li>
  <li>PowerShell</li>
  <li>Prolog</li>
  <li>Python</li>
  <li>qmake</li>
  <li>R</li>
  <li>Raku</li>
  <li>Ring</li>
  <li>RPG</li>
  <li>Ruby</li>
  <li>Rust</li>
  <li>SAS</li>
  <li>Scala</li>
  <li>Shell script
    <ul>
      <li>Bash</li>
      <li>Korn Shell</li>
    </ul>
  </li>
  <li>Simula</li>
  <li>Simulink</li>
  <li>Smalltalk</li>
  <li>Solidity</li>
  <li>SPARK</li>
  <li>SQL
    <ul>
      <li>PL/SQL</li>
      <li>PostgreSQL</li>
      <li>Snowflake</li>
    </ul>
  </li>
  <li>Swift</li>
  <li>SystemVerilog</li>
  <li>TeX
    <ul>
      <li>LaTeX</li>
    </ul>
  </li>
  <li>Tcl</li>
  <li>V</li>
  <li>Vala</li>
  <li>VBA</li>
  <li>VBScript</li>
  <li>VHDL</li>
  <li>Vim script</li>
  <li>Visual Basic</li>
  <li>Wolfram Language</li>
  <li>X++</li>
  <li>Zig</li>
</ul>

<p> </p>

<p>[<a href="https://survey.stackoverflow.co/2024/technology#1-programming-scripting-and-markup-languages">so2024</a>] [<a href="https://www.tiobe.com/tiobe-index/">tiobe</a>] [<a href="https://spectrum.ieee.org/top-programming-languages-2024">ieee</a>] [<a href="https://innovationgraph.github.com/global-metrics/programming-languages">github</a>] [<a href="https://godbolt.org/api/languages">godbolt</a>] [<a href="https://stackoverflow.com/tags?tab=popular">so-tags</a>] [<a href="https://sources.debian.org/stats">debian</a>]</p>

<h2 id="getting-length-of-array-like-objects">Getting length of array-like objects</h2>

<h3 id="languages-using-size">Languages using "size"</h3>

<ul>
  <li>ALGOL [<a href="https://public.support.unisys.com/aseries/docs/ClearPath-MCP-21.0/86000098-519/86000098-519.pdf">algol</a>]    (for ClearPath MCP Software by Unisys)
    <pre><code>SIZE(myArray)
</code></pre>
    <aside>
      <p>While there are some indicators some other implementations might have
ways to compute the size from array bounds, I wasn't able to confirm.
Classic dialects seems to be void of any such capabilities.</p>
    </aside>
  </li>
  <li>Apex [<a href="https://stackoverflow.com/a/18043420">apex</a>]
    <pre><code>myArray.size()
</code></pre>
  </li>
  <li>C++ [<a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4950.pdf">cpp1</a>] [<a href="https://en.cppreference.com/w/cpp/container/array/size">cpp2</a>] [<a href="https://en.cppreference.com/w/cpp/iterator/size">cpp3</a>]
    <pre><code>std::size(myArray)
myVector.size()
myStdArray.size()       // `myStdArray` being of type std::array
</code></pre>
  </li>
  <li>CHILL [<a href="https://www.itu.int/rec/dologin_pub.asp?lang=e&amp;id=T-REC-Z.200-199911-I!!PDF-E">chill</a>]
    <pre><code>SIZE(myArray)
</code></pre>
  </li>
  <li>Common Lisp [<a href="https://quickref.common-lisp.net/array-operations.html#index-size">common-lisp-1</a>]
    <pre><code>(size myArray)
</code></pre>
  </li>
  <li>Crystal [<a href="https://crystal-lang.org/api/1.13.3/Array.html#size%3AInt32-instance-method">crystal</a>]
    <pre><code>myArray.size
</code></pre>
  </li>
  <li>Curl [<a href="https://www.curlap.com/support/developers/curl/docs/rte/latest/en/docs/en/api-ref/Array-of.html#size">curl</a>]
    <pre><code>size(myArray)
</code></pre>
  </li>
  <li>GDScript [<a href="https://docs.godotengine.org/en/stable/classes/class_array.html#class-array-method-size">gdscript</a>]
    <pre><code>myArray.size()
</code></pre>
  </li>
  <li>Erlang [<a href="https://www.erlang.org/doc/apps/stdlib/array.html#size/1">erlang1</a>]
    <pre><code>array:size(myArray)
</code></pre>
  </li>
  <li>Fortran [<a href="https://www.intel.com/content/www/us/en/docs/fortran-compiler/developer-guide-reference/2024-2/size-function.html">fortran1</a>] [<a href="https://gcc.gnu.org/onlinedocs/gcc-13.3.0/gfortran/SIZE.html">fortran2</a>]
    <pre><code>SIZE(myArray)
</code></pre>
  </li>
  <li>Groovy [<a href="https://docs.groovy-lang.org/latest/html/documentation/core-syntax.html#_arrays">groovy1</a>] [<a href="https://docs.groovy-lang.org/next/html/groovy-jdk/primitives-and-primitive-arrays/int[].html#size()">groovy2</a>]
    <pre><code>myArray.size()
</code></pre>
  </li>
  <li>Java [<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html">java2</a>]
    <pre><code>ArrayList.size()
</code></pre>
  </li>
  <li>Julia [<a href="https://docs.julialang.org/en/v1/base/arrays/">julia1</a>] [<a href="https://stackoverflow.com/a/57515368">julia2</a>]
    <pre><code>size(myArray)[1]
size(myArray, 1)
</code></pre>
  </li>
  <li>Kotlin [<a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-array/size.html">kotlin1</a>] [<a href="https://kotlinandroid.org/kotlin/array/kotlin-array-size/">kotlin2</a>]
    <pre><code>myArray.size
</code></pre>
  </li>
  <li>
    <p>LabVIEW [<a href="https://labviewwiki.org/wiki/Array_Size_function">labview</a>]</p>

    <p>     <em>Array Size</em> function</p>

    <p> </p>
  </li>
  <li>Maple [<a href="https://www.maplesoft.com/support/help/maple/view.aspx?path=ArrayTools%2FSize">maple</a>]
    <pre><code>Size(myArray)
</code></pre>
  </li>
  <li>MATLAB [<a href="https://www.mathworks.com/help/matlab/ref/double.size.html">matlab</a>]
    <pre><code>size(myArray)
</code></pre>
  </li>
  <li>MQL5 [<a href="https://www.mql5.com/en/docs/array/arraysize">mql5</a>]
    <pre><code>ArraySize(myArray)
</code></pre>
  </li>
  <li>occam 2 [<a href="https://homepages.inf.ed.ac.uk/stark/ipp/manuals/occam-2-1.pdf">occam</a>]
    <pre><code>SIZE myArray
</code></pre>
  </li>
  <li>PHP [<a href="https://www.php.net/manual/en/function.sizeof.php">php2</a>]    <sub>(alias for <code>count()</code>)</sub>
    <pre><code>sizeof($myArray)
</code></pre>
  </li>
  <li>qmake [<a href="https://doc.qt.io/qt-6/qmake-function-reference.html#size-variablename">qmake</a>]
    <pre><code>$$size(myList)
</code></pre>
  </li>
  <li>Ruby [<a href="https://docs.ruby-lang.org/en/master/Array.html#method-i-size">ruby2</a>] [<a href="https://www.rubyinrails.com/2014/01/15/ruby-count-vs-length-vs-size/">ruby4</a>]    <sub>(alias for <code>.length</code>)</sub>
    <pre><code>myArray.size
</code></pre>
  </li>
  <li>Smalltalk [<a href="https://wiki.squeak.org/squeak/3235">smalltalk</a>]
    <pre><code>myArray size.
</code></pre>
  </li>
  <li>Snowflake [<a href="https://docs.snowflake.com/en/sql-reference/functions/array_size">snowflake</a>]
    <pre><code>SELECT ARRAY_SIZE(ARRAY_CONSTRUCT(1, 2, 3)) AS SIZE;
</code></pre>
  </li>
  <li>SPARK [<a href="https://sparkbyexamples.com/spark/spark-get-size-length-of-array-map-column/">spark</a>]
    <pre><code>size($"myArray")
</code></pre>
  </li>
  <li>SystemVerilog [<a href="https://stackoverflow.com/a/33671359">verilog</a>]
    <pre><code>myArray.size
$size(myArray)
</code></pre>
  </li>
  <li>Tcl [<a href="https://wiki.tcl-lang.org/page/array+size">tcl</a>]
    <pre><code>array size myArray
</code></pre>
  </li>
</ul>

<h3 id="languages-using-length">Languages using "length"</h3>

<ul>
  <li>ActionScript [<a href="https://www.oreilly.com/library/view/actionscript-the-definitive/1565928520/re07.html">actionscript</a>]
    <pre><code>myArray.length
</code></pre>
  </li>
  <li>Ada [<a href="https://www.adaic.org/resources/add_content/standards/22rm/rm-final.pdf">ada1</a>] [<a href="https://learn.adacore.com/courses/intro-to-ada/chapters/arrays.html">ada2</a>] [<a href="https://ada-lang.io/docs/arm/AA-3/AA-3.6/#p9_3.6.2">ada3</a>]
    <pre><code>myArray'Length
</code></pre>
  </li>
  <li>C# [<a href="https://learn.microsoft.com/en-us/dotnet/api/system.array.length">csharp1</a>] [<a href="https://learn.microsoft.com/en-us/dotnet/api/system.array.length">csharp2</a>]
    <pre><code>myArray.Length
myArray.GetLength()
</code></pre>
  </li>
  <li>CLIPS [<a href="https://clipsrules.net/documentation/v641/apg641.pdf">clips1</a>] [<a href="https://stackoverflow.com/a/44165009">clips2</a>]
    <pre><code>(length$ ?myArray)
</code></pre>
  </li>
  <li>Clojure [<a href="https://clojuredocs.org/clojure.core/alength">clojure1</a>] [<a href="http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/alength">clojure2</a>]
    <pre><code>(alength myArray)
</code></pre>
  </li>
  <li>CMake [<a href="https://cmake.org/cmake/help/latest/command/list.html#length">cmake</a>]
    <pre><code>list(LENGTH myList n)
</code></pre>
  </li>
  <li>Cobra [<a href="http://cobra-language.com/how-to/UseArrays/">cobra1</a>]
    <pre><code>myArray.length
</code></pre>
  </li>
  <li>ColdFusion [<a href="https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/functions-a-b/arraylen.html">cfml</a>]
    <pre><code>ArrayLen(myArray)
</code></pre>
  </li>
  <li>D [<a href="https://dlang.org/spec/arrays.html#array-length">dlang</a>]
    <pre><code>myArray.length
</code></pre>
  </li>
  <li>Dart [<a href="https://dart.dev/language/collections#lists">dart</a>]
    <pre><code>myList.length
</code></pre>
  </li>
  <li>Emacs Lisp [<a href="https://ftp.gnu.org/old-gnu/Manuals/elisp-manual-20-2.5/html_chapter/elisp_7.html">emacs</a>]
    <pre><code>(length mySeq)
</code></pre>
  </li>
  <li>Elixir [<a href="https://hexdocs.pm/elixir/1.17.3/Kernel.html#length/1">elixir</a>]
    <pre><code>length(myList)
</code></pre>
  </li>
  <li>Elm [<a href="https://package.elm-lang.org/packages/elm/core/latest/Array#length">elm</a>]
    <pre><code>length(myArray)
</code></pre>
  </li>
  <li>Erlang [<a href="https://www.erlang.org/docs/26/man/erlang#length-1">erlang2</a>]
    <pre><code>length(myList)
</code></pre>
  </li>
  <li>F# [<a href="https://fsharp.github.io/fsharp-core-docs/reference/fsharp-collections-arraymodule.html#length">fsharp</a>]
    <pre><code>myArray |&gt; Array.Length
myArray |&gt; Array.length
</code></pre>
  </li>
  <li>FoxPro [<a href="https://learn.microsoft.com/en-us/previous-versions/visualstudio/foxpro/aa977250(v=vs.71)">foxpro1</a>] [<a href="https://hackfox.github.io/section4/s4g214.html">foxpro2</a>] [<a href="https://www.vfphelp.com/help/html/8496659e-83b9-4e08-847b-f93b1e791ee5.htm">foxpro3</a>]
    <pre><code>ALEN(myArray)
</code></pre>
  </li>
  <li>gawk [<a href="https://www.gnu.org/software/gawk/manual/gawk.html">gawk</a>]
    <pre><code>length(myArray)
</code></pre>
  </li>
  <li>GLSL [<a href="https://www.khronos.org/opengl/wiki/Data_Type_(GLSL)#Arrays">glsl</a>]
    <pre><code>myArray.length()
</code></pre>
  </li>
  <li>Go [<a href="https://pkg.go.dev/builtin#len">go</a>]
    <pre><code>len(myArray)
</code></pre>
  </li>
  <li>Haskell [<a href="https://hackage.haskell.org/package/base-4.20.0.1/docs/Data-List.html#v:length">haskell</a>]
    <pre><code>length myList
</code></pre>
  </li>
  <li>Java [<a href="https://stackoverflow.com/a/27673843">java1</a>] [<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html">java2</a>]
    <pre><code>myArray.length
</code></pre>
  </li>
  <li>JavaScript / TypeScript / CoffeeScript / JScript  [<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length">js</a>]
    <pre><code>myArray.length
</code></pre>
  </li>
  <li>Julia [<a href="https://docs.julialang.org/en/v1/base/arrays/">julia1</a>] [<a href="https://stackoverflow.com/a/57515368">julia2</a>]
    <pre><code>length(myArray)
</code></pre>
  </li>
  <li>Mojo [<a href="https://docs.modular.com/mojo/stdlib/builtin/len/">mojo</a>]
    <pre><code>len(myList)
</code></pre>
  </li>
  <li>Nim [<a href="https://nim-lang.org/docs/manual.html#types-array-and-sequence-types">nim1</a>] [<a href="https://nimbyexample.com/arrays.html">nim2</a>]
    <pre><code>len(myArray)
myArray.len
</code></pre>
  </li>
  <li>OCaml [<a href="https://ocaml.org/manual/5.2/api/Array.html">ocaml1</a>] [<a href="https://stackoverflow.com/a/57106170">ocaml2</a>]
    <pre><code>Array.length myArray
</code></pre>
  </li>
  <li>Odin [<a href="https://pkg.odin-lang.org/base/builtin/#len">odin</a>]
    <pre><code>len(myArray)
</code></pre>
  </li>
  <li>Pascal / Object Pascal / Delphi [<a href="https://www.freepascal.org/docs-html/rtl/system/length.html">pascal1</a>] [<a href="https://smartpascal.github.io/help/assets/length.htm">pascal2</a>]
    <pre><code>Length(myArray)
</code></pre>
  </li>
  <li>PostgreSQL [<a href="https://www.postgresql.org/docs/current/functions-array.html#ARRAY-FUNCTIONS-TABLE">postgresql</a>]
    <pre><code>SELECT array_length(myArray, 1) FROM table;
</code></pre>
  </li>
  <li>PostScript [<a href="https://www.adobe.com/jp/print/postscript/pdfs/PLRM.pdf">postscript1</a>] [<a href="http://www.linuxfocus.org/English/July1999/article100.html">postscript2</a>] [<a href="https://github.com/Chubek/postscript-dossier/blob/master/ps-arrays.md#operations-on-arrays">postscript3</a>]
    <pre><code>myArray length
</code></pre>
  </li>
  <li>PowerShell [<a href="https://devblogs.microsoft.com/scripting/powertip-find-number-elements-in-a-powershell-array/">ps1</a>] [<a href="https://learn.microsoft.com/en-us/powershell/scripting/lang-spec/chapter-07?view=powershell-7.4#7141-subscripting-an-array">ps2</a>]
    <pre><code>$myArray.Length
</code></pre>
  </li>
  <li>Prolog [<a href="https://www.swi-prolog.org/pldoc/man?predicate=length/2">prolog1</a>] [<a href="https://en.wikipedia.org/w/index.php?title=Prolog&amp;oldid=1246276957#Predicates_and_programs">prolog2</a>]
    <pre><code>length(myList, L)
</code></pre>
  </li>
  <li>Python [<a href="https://docs.python.org/3/library/functions.html#len">python</a>]
    <pre><code>len(myList)
</code></pre>
  </li>
  <li>R [<a href="https://cran.r-project.org/doc/manuals/r-release/R-intro.html">r1</a>] [<a href="https://rforhealthcare.org/array-sizes/">r2</a>] [<a href="https://www.educative.io/answers/how-to-obtain-the-length-of-an-array-in-r">r3</a>]
    <pre><code>length(myArray)
</code></pre>
  </li>
  <li>Racket [<a href="https://docs.racket-lang.org/array/index.html#%28def._%28%28lib._array%2Fmain..rkt%29._array-length%29%29">racket</a>]
    <pre><code>(array-length myArray)
</code></pre>
  </li>
  <li>Ring [<a href="https://ring-lang.github.io/doc1.20/lists.html#get-list-size">ring</a>]
    <pre><code>Len(myList)
</code></pre>
  </li>
  <li>Ruby [<a href="https://docs.ruby-lang.org/en/master/Array.html#method-i-length">ruby1</a>] [<a href="https://www.rubyinrails.com/2014/01/15/ruby-count-vs-length-vs-size/">ruby4</a>]
    <pre><code>myArray.length
</code></pre>
  </li>
  <li>Rust [<a href="https://doc.rust-lang.org/std/primitive.array.html">rust</a>]
    <pre><code>myArray.len()
</code></pre>
  </li>
  <li>Scala [<a href="https://docs.scala-lang.org/overviews/collections-2.13/arrays.html">scala</a>]
    <pre><code>myArray.length
</code></pre>
  </li>
  <li>Scheme [<a href="https://docs.scheme.org/schintro/schintro_41.html">scheme1</a>] [<a href="https://groups.csail.mit.edu/mac/ftpdir/scheme-7.4/doc-html/scheme_9.html">scheme2</a>]
    <pre><code>(length myList)
(vector-length myVector)
</code></pre>
  </li>
  <li>Solidity [<a href="https://docs.soliditylang.org/en/latest/types.html">solidity1</a>] [<a href="https://www.geeksforgeeks.org/solidity-arrays/">solidity2</a>]
    <pre><code>myArray.length
</code></pre>
  </li>
  <li>Standard ML [<a href="https://smlfamily.github.io/Basis/array.html">std-ml</a>]
    <pre><code>Array.length myArray
</code></pre>
  </li>
  <li>V [<a href="https://docs.vlang.io/v-types.html#array-fields">vlang</a>]
    <pre><code>myArray.len
</code></pre>
  </li>
  <li>Vala [<a href="https://docs.vala.dev/tutorials/programming-language/main/02-00-basics/02-04-data-types.html#arrays">vala</a>]
    <pre><code>myArray.length[0]
</code></pre>
  </li>
  <li>VHDL [<a href="https://vhdlguide.com/2018/05/28/attribute-length/">vhdl1</a>] [<a href="https://nandland.com/list-of-tick-attributes/">vhdl2</a>]
    <pre><code>myArray'LENGTH
</code></pre>
  </li>
  <li>Vim script [<a href="https://vimhelp.org/builtin.txt.html#len%28%29">vim</a>]
    <pre><code>len(myList)
myList-&gt;len()
</code></pre>
  </li>
  <li>Visual Basic [<a href="https://learn.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/arrays/">vb</a>]
    <pre><code>myArray.Length
myArray.GetLength()
</code></pre>
  </li>
  <li>Wolfram Language [<a href="https://reference.wolfram.com/language/ref/Length.html">wolfram</a>]
    <pre><code>Length[myArray]
</code></pre>
  </li>
  <li>Zig [<a href="https://ziglang.org/documentation/master/#Arrays">zig1</a>] [<a href="https://zig-by-example.com/arrays">zig2</a>]
    <pre><code>myArray.len
</code></pre>
  </li>
</ul>

<h3 id="languages-using-count">Languages using "count"</h3>

<ul>
  <li>Clojure [<a href="http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/count">clojure3</a>]
    <pre><code>(count myCollection)
</code></pre>
  </li>
  <li>Cobra [<a href="http://cobra-language.com/how-to/UseLists/">cobra2</a>]
    <pre><code>myList.count
</code></pre>
  </li>
  <li>Eiffel [<a href="https://www.maths.tcd.ie/~odunlain/eiffel/html/base/ARRAY.html">eiffel</a>]
    <pre><code>myArray.count
</code></pre>
  </li>
  <li>Hack [<a href="https://docs.hhvm.com/hsl/reference/function/HH.Lib.C.count/">hack</a>]
    <pre><code>C\count($myArray)
</code></pre>
  </li>
  <li>Logo [<a href="https://www.calormen.com/jslogo/language.html">logo</a>]
    <pre><code>count :myArray
</code></pre>
  </li>
  <li>PHP [<a href="https://www.php.net/manual/en/function.count.php">php1</a>]
    <pre><code>count($myArray)
</code></pre>
  </li>
  <li>PL/SQL [<a href="https://docs.oracle.com/cd/E11882_01/appdev.112/e25519/composites.htm#CIHGJCHF">plsql1</a>]
    <pre><code>myTable.COUNT
</code></pre>
  </li>
  <li>PowerShell [<a href="https://devblogs.microsoft.com/scripting/powertip-find-number-elements-in-a-powershell-array/">ps1</a>]
    <pre><code>$myArray.Count
</code></pre>
  </li>
  <li>Ruby [<a href="https://docs.ruby-lang.org/en/master/Array.html#method-i-count">ruby3</a>] [<a href="https://www.rubyinrails.com/2014/01/15/ruby-count-vs-length-vs-size/">ruby4</a>]
    <pre><code>myArray.count
</code></pre>
  </li>
  <li>SQL [<a href="https://learn.microsoft.com/en-us/sql/t-sql/functions/count-transact-sql">sql1</a>] [<a href="https://www.sqltutorial.org/sql-aggregate-functions/sql-count/">sql2</a>]
    <pre><code>SELECT COUNT(*) FROM table;
</code></pre>
  </li>
  <li>Swift [<a href="https://developer.apple.com/documentation/swift/array/count">swift</a>]
    <pre><code>myArray.count
</code></pre>
  </li>
</ul>

<h3 id="languages-using-other-words">Languages using other words</h3>

<ul>
  <li>ABAP [<a href="https://help.sap.com/doc/abapdocu_752_index_htm/7.52/en-US/abendescriptive_functions_table.htm">abap1</a>] [<a href="https://stackoverflow.com/q/394375">abap2</a>]
    <pre><code>LINES(myTable)
</code></pre>
  </li>
  <li>C++ [<a href="https://en.cppreference.com/w/cpp/container/vector/capacity">cpp4</a>] [<a href="https://en.cppreference.com/w/cpp/types/extent">cpp5</a>] [<a href="https://godbolt.org/z/nEPKP79fY">cpp6</a>]
    <pre><code>myVector.capacity()

std::extent&lt;decltype(myArray)&gt;::value
std::extent_v&lt;decltype(myArray)&gt;
</code></pre>
  </li>
  <li>Common Lisp [<a href="https://lispcookbook.github.io/cl-cookbook/data-structures.html#sizes">common-lisp-2</a>]
    <pre><code>(array-dimension myArray 0)
</code></pre>
  </li>
  <li>GAMS [<a href="https://www.gams.com/latest/docs/index.html">gams1</a>] [<a href="https://forum.gams.com/t/finding-length-of-set/578">gams2</a>]
    <pre><code>card(mySet)
</code></pre>
  </li>
  <li>GNU Make [<a href="https://www.gnu.org/software/make/manual/html_node/Text-Functions.html#index-words">gmake</a>]
    <pre><code>$(words $(myList))
</code></pre>
  </li>
  <li>Lua [<a href="https://www.lua.org/pil/19.1.html">lua</a>]
    <pre><code>table.getn(myArray)
</code></pre>
  </li>
  <li>Modula-2 [<a href="https://www.modula2.org/tutor/chapter6.php">modula2</a>]
    <pre><code>HIGH(myArray)+1
</code></pre>
  </li>
  <li>Modula-3 [<a href="https://modula3.github.io/cm3/reference/complete/html/2_6_13Type_operations.html">modula3</a>]
    <pre><code>NUMBER(myArray)
</code></pre>
  </li>
  <li>PL/I [<a href="https://www.ibm.com/docs/en/SSY2V3_5.1.0/com.ibm.ent.pl1.zos.doc/lrm.pdf">pli1</a>] [<a href="https://www.microfocus.com/documentation/openpli/80/pfbltn.htm#dimension">pli2</a>]
    <pre><code>DIM(myArray,1)
</code></pre>
  </li>
  <li>PL/SQL [<a href="https://docs.oracle.com/cd/B28359_01/server.111/b28286/functions015.htm#SQLRF06305">plsql2</a>]
    <pre><code>CARDINALITY(myTab)
</code></pre>
  </li>
  <li>Raku [<a href="https://docs.raku.org/type/Array#method_elems">raku</a>]
    <pre><code>@myArray.elems
</code></pre>
  </li>
  <li>RPG [<a href="https://www.ibm.com/docs/en/i/7.5?topic=functions-elem-get-number-elements">rpg</a>]
    <pre><code>%ELEM(myArray)
</code></pre>
  </li>
  <li>
    <p>Simulink [<a href="https://www.mathworks.com/matlabcentral/answers/51183-get-array-size-in-simulink">simulink1</a>] [<a href="https://www.mathworks.com/help/simulink/slref/width.html">simulink2</a>]</p>

    <p>     <em>Width</em> block</p>

    <p> </p>
  </li>
  <li>SAS [<a href="https://support.sas.com/resources/papers/97529_Using_Arrays_in_SAS_Programming.pdf">sas</a>]
    <pre><code>dim(myArray)
</code></pre>
  </li>
  <li>X++ [<a href="https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/dev-ref/xpp-reflection-run-time-functions#dimof">xpp</a>]
    <pre><code>dimOf(myArray)
</code></pre>
  </li>
</ul>

<h3 id="languages-using-symbols">Languages using symbols</h3>

<ul>
  <li>APL [<a href="https://stackoverflow.com/a/56243457">apl</a>]
    <pre><code>⍴ myArray
≢ myArray
</code></pre>
  </li>
  <li>Bash [<a href="https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html">bash</a>]
    <pre><code>${#myArray[@]}
</code></pre>
  </li>
  <li>C Shell <a href="https://linux.die.net/man/1/csh">csh</a>
    <pre><code>$#myArray
</code></pre>
  </li>
  <li>Icon [<a href="https://www2.cs.arizona.edu/icon/refernce/prefix.htm#size">icon</a>]
    <pre><code>*myArray
</code></pre>
  </li>
  <li>Korn Shell [<a href="https://docstore.mik.ua/orelly/unix3/korn/ch06_04.htm">korn1</a>] [<a href="https://linux.die.net/man/1/ksh">korn2</a>]
    <pre><code>${#myArray[*]}
${#myArray[@]}
</code></pre>
  </li>
  <li>Perl [<a href="https://stackoverflow.com/a/7407036">perl</a>]
    <pre><code>@myArray
</code></pre>
  </li>
  <li>Shell script [<a href="https://pubs.opengroup.org/onlinepubs/9799919799/utilities/V3_chap02.html">sh</a>]
    <pre><code>$#
</code></pre>
    <aside>
      <p>(only one array per script/subshell/function in standard POSIX Shell)</p>
    </aside>
  </li>
</ul>

<h3 id="languages-where-length-is-computed">Languages where length is computed</h3>

<ul>
  <li>AWK
    <pre><code>n = 0; for (a in myArray) n++
</code></pre>
  </li>
  <li>BASIC
    <pre><code>n = 0
FOR i = 0 TO N  ' assuming N as an upper limit for all arrays
        ON ERROR GOTO FoundLength
        temp = myArray(i)
        n = length + 1
NEXT i
FoundLength:
</code></pre>
  </li>
  <li>Batch files [<a href="https://www.geeksforgeeks.org/batch-script-length-of-an-array/">batch</a>]
    <pre><code>set n=0
:Loop
if define myArray[%n%] (
   set /a n += 1
   goto :Loop
)
</code></pre>
  </li>
  <li>C / C++ / Objective-C  [<a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3369.pdf">n3369</a>]
    <pre><code>sizeof myArray / sizeof myArray[0]
</code></pre>
  </li>
  <li>COBOL [<a href="https://www.ibm.com/docs/en/cobol-zos/6.4?topic=functions-length">cobol1</a>] [<a href="https://www.ibm.com/docs/en/cobol-zos/6.4?topic=registers-length">cobol2</a>] [<a href="https://godbolt.org/z/KMMv58MoK">cobol3</a>]
    <pre><code>COMPUTE n = LENGTH OF myArray / LENGTH OF myArray-element
</code></pre>
  </li>
  <li>Makefile
    <pre><code>N := `echo $(myList) | wc -w`
</code></pre>
    <aside>
      <p>(unreliable and requires "passing" the list to another language)</p>
    </aside>
  </li>
  <li>Simula [<a href="https://portablesimula.github.io/github.io/doc/SimulaStandard.pdf">simula</a>]
    <pre><code>upperbound(myArray,1) - lowerbound(myArray,1) + 1
</code></pre>
  </li>
  <li>VBA / VBScript  [<a href="https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/ubound-function#remarks">vba</a>] [<a href="https://stackoverflow.com/a/73277957">vbscript</a>]
    <pre><code>UBound(myArray) - LBound(myArray) + 1
</code></pre>
  </li>
</ul>

<h3 id="languages-where-arrays-are-implemented-by-users">Languages where arrays are implemented by users</h3>

<ul>
  <li>Forth</li>
  <li>TeX / LaTeX</li>
</ul>

<h2 id="observations">Observations</h2>

<ul>
  <li>
    <p>Some of the listed languages provide multiple ways of retrieving number
of elements. Sometimes the ways are equivalent, but usually the underlying
mechanism is different.</p>

    <ul>
      <li>e.g. Ruby has <code>.length</code>, but <code>.count</code> without condition also gives
the number of elements;</li>
      <li>e.g. C++ allows calculating array length via <code>sizeof arr / sizeof arr[0]</code>,
by using <code>std::size()</code> function, by passing the type to <code>std::extent_v&lt;T&gt;</code>
trait template, and couple other ways.</li>
    </ul>

    <p>If such additional method was not a primary or prominent way,
or at least from the focus group, it might be missing from the list.</p>
  </li>
  <li>
    <p>The vast majority of languages use derivatives of either "length" or "size",
with "length" being the dominat base.</p>
  </li>
  <li>
    <p>"Length" and "size" are also often used for other linear data structures
beside arrays, like strings, linked lists, queues, etc.</p>
  </li>
  <li>
    <p>Documentations, specifications and communities use terms "length" and "size"
quite freely and interchangeably in the meaning of "the number of elements
in data structure". Sometimes languages make them alias one another.</p>

    <ul>
      <li>Other words also sometimes are seen as synonyms, although rarely and/or in
specific contexts (e.g. "dimension" or "extent" would primarily be present
when generalizing to multi-dimensional arrays).</li>
    </ul>
  </li>
  <li>
    <p>"Count" is 3rd most popular choice, albeit significantly lesser number of
languages represent this category. Sometimes it is a side effect of more
versatile feature (e.g. in meaning "count of X in Y", where Y might contain
more than just Xs).</p>
  </li>
  <li>
    <p>4th most common word is "dimension"; 5th are ex aequo "elements" and "cardinality".
Including methods of calculating number of elements puts "bounds" in top 5 too.</p>
  </li>
</ul>

<p> </p>

<p>##</p>

<p><a href="https://www.reddit.com/r/ProgrammerHumor/comments/1gxf7ll/pleaseagreeononename/"><img src="https://i.redd.it/yexhn9of1i2e1.png" alt="ProgrammerHumor" /></a></p>]]></content><author><name>Jorenar</name></author><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Generation 2½ of video game consoles</title><link href="https://jorenar.com/two-half-console-gen" rel="alternate" type="text/html" title="Generation 2½ of video game consoles" /><published>2023-11-01T00:00:00+00:00</published><updated>2023-11-01T00:00:00+00:00</updated><id>https://jorenar.com/two-half-console-gen</id><content type="html" xml:base="https://jorenar.com/two-half-console-gen"><![CDATA[<p>Initially I wanted to write a full fledged text about the topic, but then I've found
a decade old article <a href="https://web.archive.org/web/20150314024810/http://revrob.com/sci-a-tech-topmenu-52/233-why-the-second-generation-of-video-game-consoles-is-really-two-distinct-and-separate-generations">Why the Second Generation of Video Game Consoles Is Really Two
Distinct and Separate Generations</a> by Rev. Robert A. Vinciguerra
on the archive of their blog <a href="https://web.archive.org/web/20151026123656/http://www.revrob.com/">The Rev. Rob Times</a>, which more or
less encapsulates what I've planned to say...</p>

<p>Therefore, I'm limiting myself to short note with few links:</p>

<ul>
  <li><a href="https://web.archive.org/web/20150314024810/http://revrob.com/sci-a-tech-topmenu-52/233-why-the-second-generation-of-video-game-consoles-is-really-two-distinct-and-separate-generations">Why the Second Generation of Video Game Consoles Is Really Two Distinct and Separate Generations</a>
    <ul>
      <li><a href="https://www.reddit.com/r/gamecollecting/comments/1w2nf8/why_the_second_generation_of_video_game_consoles/">discussion on r/gamecollecting under blogpost</a></li>
      <li><a href="https://www.reddit.com/r/retrogaming/comments/2gowa3/how_the_second_generation_of_video_game_consoles/">discussion on r/retrogaming under graphic from the blogpost</a></li>
    </ul>
  </li>
  <li><a href="https://en.wikipedia.org/wiki/Talk:Second_generation_of_video_game_consoles#Are_Colecovision_and_Atari_5200_really_second_gen?">Talk:Second generation of video game consoles#Are Colecovision and Atari 5200 really second gen? - Wikipedia</a></li>
  <li><a href="https://en.wikipedia.org/wiki/Talk:ColecoVision#Generation">Talk:ColecoVision#Generation - Wikipedia</a>
    <ul>
      <li><a href="https://archive.org/details/tv-gamer-magazine-1983-01/page/n41">TV Gamer Magazine (January 1983) : Internet Archive</a></li>
      <li><a href="https://archive.org/details/Video_Games_Volume_1_Number_04_1983-01_Pumpkin_Press_US/page/n71">Video Games - Volume 1 Number 04 (1983-01)(Pumpkin Press)(US) : Internet Archive</a></li>
      <li><a href="https://vgpavilion.com/mags/1982/fall/vgp/fall-1982-video-game-buyers-guide/">Video Games Player, Issue 1, Fall 1982</a></li>
      <li><a href="https://www.informit.com/articles/article.aspx?p=378141&amp;seqNum=3">Third Generation: 1982-1984 - A History of Home Video Game Consoles - InformIT</a></li>
    </ul>
  </li>
  <li><a href="https://forum.digitpress.com/forum/showthread.php?173587-Video-game-generation-between-2nd-and-3rd">Video game generation between 2nd and 3rd? - Retrogaming Roundtable</a></li>
  <li><a href="https://blackfalcongames.net/?p=179">Console Generations: The Missing Videogame Generation - Black Falcon Games</a></li>
</ul>]]></content><author><name>Jorenar</name></author><summary type="html"><![CDATA[Initially I wanted to write a full fledged text about the topic, but then I've found a decade old article Why the Second Generation of Video Game Consoles Is Really Two Distinct and Separate Generations by Rev. Robert A. Vinciguerra on the archive of their blog The Rev. Rob Times, which more or less encapsulates what I've planned to say...]]></summary></entry><entry><title type="html">Creating rootfs.tar.gz from Linux LiveCD</title><link href="https://jorenar.com/livecd-2-rootfs-tar-gz" rel="alternate" type="text/html" title="Creating rootfs.tar.gz from Linux LiveCD" /><published>2023-10-05T00:00:00+00:00</published><updated>2023-10-05T00:00:00+00:00</updated><id>https://jorenar.com/livecd-2-rootfs-tar-gz</id><content type="html" xml:base="https://jorenar.com/livecd-2-rootfs-tar-gz"><![CDATA[<p>While the user facing part of LiveCD works mostly the same across Linux distros,
the internals can be more or less different. That's why in this text I'll present
how to extract filesystem from two distributions: Debian and Fedora. That ought
to give anyone enough overview to reproduce for any other distribution.</p>

<h2 id="tldr">TL;DR</h2>

<p><strong>Debian</strong></p>
<pre><code>sudo mkdir /mnt/iso
sudo mount -o loop debian-live-12.1.0-amd64-standard.iso /mnt/iso
cd /mnt/iso
sudo unsquashfs -d /tmp/squashfs ./live/filesystem.squashfs
cd /tmp/squashfs
sudo tar -vzcp -f ~/rootfs.tar.gz .
sudo chown $USER:$USER ~/rootfs.tar.gz
cd ~
sudo umount /mnt/iso
sudo rmdir /mnt/iso
sudo rm -r /tmp/squashfs
</code></pre>

<p><strong>Fedora</strong></p>
<pre><code>sudo mkdir /mnt/iso
sudo mount -o loop Fedora-Workstation-Live-x86_64-38-1.6.iso /mnt/iso
cd /mnt/iso
sudo unsquashfs -d /tmp/squashfs ./LiveOS/squashfs.img
cd /tmp/squashfs
sudo mkdir /mnt/rootfs
sudo mount -o loop LiveOS/rootfs.img /mnt/rootfs
cd /mnt/rootfs
sudo tar -vzcp -f ~/rootfs.tar.gz .
sudo chown $USER:$USER ~/rootfs.tar.gz
cd ~
sudo umount /mnt/iso
sudo umount /mnt/rootfs
sudo rmdir /mnt/iso /mnt/rootfs
sudo rm -r /tmp/squashfs
</code></pre>

<h1 id="prerequisites">Prerequisites</h1>

<ul>
  <li>Linux environment (probably any other *nix will also do)</li>
  <li><code>tar</code> program</li>
  <li><code>unsquashfs</code> - usually part of <a href="https://github.com/plougher/squashfs-tools">squashfs-tools</a>
               package (<a href="https://command-not-found.com/unsquashfs">see at command-not-found.com</a>)</li>
  <li><code>mount</code></li>
  <li><code>sudo</code> + permissions</li>
</ul>

<h1 id="step-by-step">Step-by-step</h1>
<h2 id="get-the-livecds">Get the LiveCDs</h2>

<p>This step is self-explanatory.</p>

<p>As of writing those words the latest ISOs are:</p>
<ul>
  <li><code>debian-live-12.1.0-amd64-standard.iso</code></li>
  <li><code>Fedora-Workstation-Live-x86_64-38-1.6.iso</code></li>
</ul>

<h2 id="mounting-isos">Mounting ISOs</h2>

<p>First we need to create mountpoints:</p>
<pre><code>$ sudo mkdir /mnt/debian
$ sudo mkdir /mnt/fedora
</code></pre>
<p>(it doesn't need to be <code>/mnt/iso</code>, you can as well use <code>~/foo</code> or something else)</p>

<p>The syntax for mounting an ISO file is: <code>mount -o loop disk1.iso /mnt/disk</code></p>

<p>Therefore, let's mount our images:</p>
<pre><code>$ sudo mount -o loop debian-live-12.1.0-amd64-standard.iso /mnt/debian
$ sudo mount -o loop Fedora-Workstation-Live-x86_64-38-1.6.iso /mnt/fedora
</code></pre>

<h2 id="finding-squashfs">Finding SquashFS</h2>

<pre><code>$ find /mnt/debian -name '*squashfs*'
/mnt/debian/boot/grub/i386-efi/squash4.mod
/mnt/debian/boot/grub/x86_64-efi/squash4.mod
/mnt/debian/live/filesystem.squashfs
/mnt/debian/pool-udeb/main/l/linux-signed-amd64/squashfs-modules-6.1.0-10-amd64-di_6.1.38-1_amd64.udeb
/mnt/debian/pool-udeb/main/l/linux-signed-amd64/squashfs-modules-6.1.0-9-amd64-di_6.1.27-1_amd64.udeb
$ find /mnt/fedora -name '*squashfs*'
/mnt/fedora/boot/grub2/i386-pc/squash4.mod
/mnt/fedora/LiveOS/squashfs.img
</code></pre>

<p>As we can see, we have:</p>
<ul>
  <li><code>/mnt/debian/live/filesystem.squashfs</code></li>
  <li><code>/mnt/fedora/LiveOS/squashfs.img</code></li>
</ul>

<p>Those are out files of interest.</p>

<h2 id="unsquashing">Unsquashing</h2>

<p>Now let's uncompress the files; I'll extract them in <code>$TMPDIR</code>
(be sure it has sufficient size or choose different location).</p>

<pre><code>$ TMPDIR="${TMPDIR:-/tmp}"
$ sudo unsquashfs -d "$TMPDIR"/debian /mnt/debian/live/filesystem.squashfs
$ sudo unsquashfs -d "$TMPDIR"/fedora /mnt/fedora/LiveOS/squashfs.img
</code></pre>

<p>Let's have a look at what we got so far:</p>
<pre><code>$ ls "$TMPDIR"/debian
bin@   etc/         lib@    libx32@  opt/   run/   sys/  var/
boot/  home/        lib32@  media/   proc/  sbin@  tmp/  vmlinuz@
dev/   initrd.img@  lib64@  mnt/     root/  srv/   usr/
$ ls "$TMPDIR"/fedora
LiveOS
$ ls "$TMPDIR"/fedora/LiveOS
rootfs.img
</code></pre>

<h2 id="mounting-fedora-filesystem-image">Mounting (Fedora) filesystem image</h2>

<p>As we seen in previous step, for Debian we already dug out
its filesystem, but there's only <code>rootfs.img</code> file for Fedora.
We can mount it as we did with ISOs to reach its content.</p>

<pre><code>$ sudo mkdir /mnt/fedora_fs
$ sudo mount -o loop "$TMPDIR"/fedora/LiveOS/rootfs.img /mnt/fedora_fs
$ ls /mnt/fedora_fs
afs/  boot/  etc/   lib@    lost+found/  mnt/  proc/  run/   srv/  tmp/  var/
bin@  dev/   home/  lib64@  media/       opt/  root/  sbin@  sys/  usr/
</code></pre>

<h2 id="creating-tarballs">Creating tarballs</h2>

<p>Now all that's left is just archiving the filesystems into <code>rootfs.tar.gz</code> files:</p>

<pre><code>$ cd "$TMPDIR"/debian
$ sudo tar -vzcp -f ~/debian.tar.gz .
$ sudo chown $USER:$USER ~/debian.tar.gz
</code></pre>

<pre><code>$ cd /mnt/fedora_fs
$ sudo tar -vzcp -f ~/fedora.tar.gz .
$ sudo chown $USER:$USER ~/fedora.tar.gz
</code></pre>

<h2 id="cleanup">Cleanup</h2>

<pre><code>$ sudo umount /mnt/debian /mnt/fedora /mnt/fedora_fs
$ sudo rmdir /mnt/debian /mnt/fedora /mnt/fedora_fs
$ sudo rm -r "$TMPDIR"/debian "$TMPDIR"/fedora
</code></pre>

<h1 id="done">Done</h1>

<p>Great! Now that we know how to get filesystem from Linux LiveCD ISO into <code>rootfs.tar.gz</code> archive, we can use it to e.g.
<a href="https://learn.microsoft.com/en-us/windows/wsl/use-custom-distro#import-the-tar-file-into-wsl">create an instance of Windows Subsystem for Linux (WSL)</a>.</p>]]></content><author><name>Jorenar</name></author><summary type="html"><![CDATA[While the user facing part of LiveCD works mostly the same across Linux distros, the internals can be more or less different. That's why in this text I'll present how to extract filesystem from two distributions: Debian and Fedora. That ought to give anyone enough overview to reproduce for any other distribution.]]></summary></entry><entry><title type="html">GOTOphobia considered harmful</title><link href="https://jorenar.com/gotophobia-harmful" rel="alternate" type="text/html" title="GOTOphobia considered harmful" /><published>2023-02-26T00:00:00+00:00</published><updated>2023-02-26T00:00:00+00:00</updated><id>https://jorenar.com/gotophobia-harmful</id><content type="html" xml:base="https://jorenar.com/gotophobia-harmful"><![CDATA[<blockquote>
  <p><strong>gotophobia</strong> -- fear of <code>goto</code> statement; usually caused by a lack of context,
and misunderstanding of stories from dark ages of programming. Programmers with
gotophobia tend to make their code less readable just to avoid using <code>goto</code>.</p>
</blockquote>

<p>Everybody and their grandpa knows (the meme-ish title of) Dijkstra's
<a href="https://dl.acm.org/doi/epdf/10.1145/362929.362947"><em>Letters to the editor: go to statement considered harmful</em></a>
(submitted under the title: <em>A case against the goto statement</em>),
but most forget the context of the 60s in which it was written,
things we take for granted were a novelty back then.</p>

<p>A lot of programmers learnt the craft in a world where <code>goto</code> was the main method
of flow control; even in structured languages it was easy for them to fall back
on the bad habits and techniques.
On the other hand, today we have the very opposite situation: programmers not
using <code>goto</code> when it's appropriate and abusing other constructs, what ironically
makes code only less readable. They overfocus on the <em>WHAT</em> ("remove <code>goto</code>")
rather than the <em>WHY</em> ("because it improves readability and maintainability").</p>

<p>Academic teachers parroting "<code>goto</code> evil" while not really understanding the
language they teach only worsens the matter [speaking from experience]. Because
who needs to learn good practices and discipline, right? It's obviously better
to just ignore the topic entirely and let the students later wonder why they get
<a href="https://www.explainxkcd.com/wiki/index.php/292:_goto">attacked by velociraptors</a>.</p>

<p><a href="https://lkml.org/lkml/2003/1/12/245">On 2003-01-12, Scott Robert Ladd wrote</a>:</p>
<blockquote>
  <p>A "goto" is not, in and of itself, dangerous -- it is a language feature,
one that directly translates to the jump instructions implemented in machine
code. Like pointers, operator overloading, and a host of other "perceived"
evils in programming, "goto" is widely hated by those who've been bitten by
poor programming.   <del><em>[redacted poorly expressed take]</em></del></p>

  <p>If you think people can't write spaghetti code in a "goto-less" language, I
can send you some <em>lovely</em> examples to disabuse you of that notion. ;)</p>

  <p>Used over short distances with well-documented labels, a "goto" can be more
effective, faster, and cleaner than a series of complex flags or other
constructs. The "goto" may also be safer and more intuitive than the
alternative. A "break" is a goto; a "continue" is a "goto" -- these are
statements that move the point of execution explicitly.</p>
</blockquote>

<p>Linux kernel is one thing, but if even such restrictive coding standard
as MISRA C (2012 edition) can downgrade the prohibition on <code>goto</code> from
<em>required</em> to <em>advisory</em>, I think in regular code we can safely use <code>goto</code>
in judicious manner.</p>

<p>Thus, I want to present some situations and patterns where <code>goto</code> could be
acceptable (perhaps the best?) choice and you could maybe want to <em>consider</em>
using it. I'll also try to mention <code>goto</code>-less alternatives and their potential
drawbacks (you presumably already are familiar with their advantages as well
as with the possible hitches of <code>goto</code> versions).</p>

<p><strong>Resources</strong></p>
<ul>
  <li><em>The C Programming Language, 2nd ed.</em> by Kernighan &amp; Ritchie</li>
  <li><a href="https://en.wikipedia.org/wiki/Goto#Common_usage_patterns">Goto # Common usage patterns - Wikipedia</a></li>
  <li><a href="https://stackoverflow.com/q/24451/10247460">Are there any legitimate use-cases for "goto" in a language that supports loops and functions? - Stack Overflow</a></li>
  <li><a href="https://beej.us/guide/bgc/html/split/goto.html">Beej's Guide to C Programming: <code>goto</code></a></li>
  <li><a href="https://gustedt.gitlabpages.inria.fr/modern-c/">Modern C</a> by Jens Gustedt</li>
  <li><a href="https://eli.thegreenplace.net/2009/04/27/using-goto-for-error-handling-in-c">Using goto for error handling in C</a></li>
  <li><a href="https://dl.acm.org/doi/epdf/10.1145/356635.356640">Structured Programming with <em>go to</em> Statements</a> by Donald E. Knuth</li>
  <li><a href="https://www.reddit.com/r/C_Programming/comments/g3juie/error_handling_using_goto/">Error handling using goto : r/C_Programming</a></li>
  <li><a href="https://www.kernel.org/doc/html/v6.2/process/coding-style.html#centralized-exiting-of-functions">Linux kernel coding style</a></li>
  <li><a href="https://www.cprogramming.com/tutorial/goto.html">When to use Goto in C - Cprogramming.com</a></li>
  <li><a href="https://alvaro-videla.com/2015/02/programming-myths.html">Harmful GOTOs, Premature Optimizations, and Programming Myths are the Root of all Evil</a></li>
  <li><a href="https://stackoverflow.com/q/245742/10247460">Examples of good gotos in C or C++ - Stack Overflow</a></li>
  <li><a href="https://www.youtube.com/watch?v=8bmEhtMVrhk">Should you ever use a goto? - Jacob Sorber - YouTube</a></li>
  <li><a href="https://chidiwilliams.com/posts/goto-reconsidered">GOTO Reconsidered</a></li>
  <li><a href="http://web.archive.org/web/20090320002214/http://www.ecn.purdue.edu/ParaMount/papers/rubin87goto.pdf">"GOTO Considered Harmful" Considered Harmful</a></li>
  <li><a href="https://www.reddit.com/r/C_Programming/comments/wimvdf/when_is_it_appropriate_to_use_goto/">When is it appropriate to use GOTO? : r/C_Programming</a></li>
  <li><a href="https://dl.acm.org/doi/pdf/10.1145/800194.805859">Programming With(out) the GOTO</a></li>
  <li><a href="https://geometrian.com/projects/blog/the_goto_statement_is_good_actually.html">The Go-To Statement is Good, Actually</a></li>
  <li><a href="https://wiki.sei.cmu.edu/confluence/display/c/MEM12-C.+Consider+using+a+goto+chain+when+leaving+a+function+on+error+when+using+and+releasing+resources">MEM12-C. Consider using a goto chain when leaving a function on error when using and releasing resources - SEI CERT C Coding Standard</a></li>
  <li><a href="https://stackoverflow.com/q/788903/10247460">Valid use of goto for error management in C? - Stack Overflow</a></li>
  <li><a href="https://lkml.org/lkml/2003/1/12/126">LKML: Rob Wilkens: Re: any chance of 2.6.0-test*?</a>
    <ul>
      <li><a href="https://web.archive.org/web/20130521051957/https://kerneltrap.org/node/553/2131">Linux: Using goto In Kernel Code | KernelTrap</a></li>
      <li><a href="https://koblents.com/Ches/Links/Month-Mar-2013/20-Using-Goto-in-Linux-Kernel-Code/">Using Goto in Linux Kernel Code | Koblents.com</a></li>
    </ul>
  </li>
</ul>

<p> </p>

<ul id="markdown-toc">
  <li><a href="#errorexception-handling--cleanup" id="markdown-toc-errorexception-handling--cleanup">Error/exception handling &amp; cleanup</a>    <ul>
      <li><a href="#goto-less-alternative-1-nested-ifs" id="markdown-toc-goto-less-alternative-1-nested-ifs"><code>goto</code>-less alternative 1: nested <code>if</code>s</a></li>
      <li><a href="#goto-less-alternative-2-if-not-then-clean" id="markdown-toc-goto-less-alternative-2-if-not-then-clean"><code>goto</code>-less alternative 2: if not then clean</a></li>
      <li><a href="#goto-less-alternative-3-flags" id="markdown-toc-goto-less-alternative-3-flags"><code>goto</code>-less alternative 3: flags</a></li>
      <li><a href="#goto-less-alternative-35-so-far-ok-flag" id="markdown-toc-goto-less-alternative-35-so-far-ok-flag"><code>goto</code>-less alternative 3.5: so-far-ok flag</a></li>
      <li><a href="#goto-less-alternative-4-functions" id="markdown-toc-goto-less-alternative-4-functions"><code>goto</code>-less alternative 4: functions</a></li>
      <li><a href="#goto-less-alternative-5-abuse-of-loops" id="markdown-toc-goto-less-alternative-5-abuse-of-loops"><code>goto</code>-less alternative 5: abuse of loops</a></li>
    </ul>
  </li>
  <li><a href="#restartretry" id="markdown-toc-restartretry">Restart/retry</a>    <ul>
      <li><a href="#goto-less-alternative-loop" id="markdown-toc-goto-less-alternative-loop"><code>goto</code>-less alternative: loop</a></li>
      <li><a href="#less-trivial-example" id="markdown-toc-less-trivial-example">Less trivial example</a>        <ul>
          <li><a href="#goto-version" id="markdown-toc-goto-version"><code>goto</code> version</a></li>
          <li><a href="#goto-less-version" id="markdown-toc-goto-less-version"><code>goto</code>-less version</a></li>
        </ul>
      </li>
    </ul>
  </li>
  <li><a href="#common-code-in-switch-statement" id="markdown-toc-common-code-in-switch-statement">Common code in <code>switch</code> statement</a>    <ul>
      <li><a href="#goto-less-alternative-1-functions" id="markdown-toc-goto-less-alternative-1-functions"><code>goto</code>-less alternative 1: functions</a></li>
      <li><a href="#goto-less-alternative-2-ifs" id="markdown-toc-goto-less-alternative-2-ifs"><code>goto</code>-less alternative 2: <code>if</code>s</a></li>
      <li><a href="#goto-less-alternative-3-interlacing-if-0" id="markdown-toc-goto-less-alternative-3-interlacing-if-0"><code>goto</code>-less alternative 3: interlacing <code>if (0)</code></a></li>
      <li><a href="#goto-less-alternative-capturing-lambda" id="markdown-toc-goto-less-alternative-capturing-lambda"><del><code>goto</code>-less alternative: capturing lambda</del></a></li>
    </ul>
  </li>
  <li><a href="#nested-break-labeled-continue" id="markdown-toc-nested-break-labeled-continue">Nested <code>break</code>, labeled <code>continue</code></a>    <ul>
      <li><a href="#breaking-loop-from-inside-a-switch-statement" id="markdown-toc-breaking-loop-from-inside-a-switch-statement">Breaking loop from inside a <code>switch</code> statement</a></li>
    </ul>
  </li>
  <li><a href="#simple-state-machines" id="markdown-toc-simple-state-machines">Simple state machines</a></li>
  <li><a href="#jumping-into-event-loop" id="markdown-toc-jumping-into-event-loop">Jumping into event loop</a>    <ul>
      <li><a href="#goto-less-alternative-1-guard-flag" id="markdown-toc-goto-less-alternative-1-guard-flag"><code>goto</code>-less alternative 1: guard flag</a></li>
      <li><a href="#goto-less-alternative-2-code-duplication" id="markdown-toc-goto-less-alternative-2-code-duplication"><code>goto</code>-less alternative 2: code duplication</a></li>
    </ul>
  </li>
  <li><a href="#optimizations" id="markdown-toc-optimizations">Optimizations</a></li>
  <li><a href="#structured-programming-with-go-to-statements" id="markdown-toc-structured-programming-with-go-to-statements"><em>Structured Programming with <strong>go to</strong> Statements</em></a></li>
</ul>

<h1 id="errorexception-handling--cleanup">Error/exception handling &amp; cleanup</h1>

<p>Poster child of using <code>goto</code> -- most of the time accepted, often recommended,
sometimes even straight up mandated. This idiom results in a good quality code,
because the operations of the algorithm are <em>structured</em> in a clear order,
while errors and other overhead is handled somewhere else, outside the mainline.
The alternatives make the code less readable as it's hard to spot where the
main code is buried among the error checks.</p>

<p>From SEI CERT C Coding Standard:</p>

<blockquote>
  <p>Many functions require the allocation of multiple resources. Failing and
returning somewhere in the middle of this function without freeing all of
the allocated resources could produce a memory leak. It is a common error
to forget to free one (or all) of the resources in this manner, so a <code>goto</code>
chain is the simplest and cleanest way to organize exits while preserving
the order of freed resources.</p>
</blockquote>

<pre><code class="language-c">int *foo(int bar)
{
    int *return_value = NULL;

    if (!do_something(bar)) {
        goto error_didnt_sth;
    }
    if (!init_stuff(bar)) {
        goto error_bad_init;
    }
    if (!prepare_stuff(bar)) {
        goto error_bad_prep;
    }
    return_value = do_the_thing(bar);

error_bad_prep:
    clean_stuff();
error_bad_init:
    destroy_stuff();
error_didnt_sth:
    undo_something();

    return return_value;
}
</code></pre>

<p><strong>Randomly taken real-life
<a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/clk/mmp/clk-audio.c?id=65ef13feb7ae5c0fe38c00db8ebffeb4f64a8297#n345">example from Linux kernel</a>:</strong></p>
<pre><code class="language-c">// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * MMP Audio Clock Controller driver
 *
 * Copyright (C) 2020 Lubomir Rintel &lt;lkundrak@v3.sk&gt;
 */

static int mmp2_audio_clk_probe(struct platform_device *pdev)
{
	struct mmp2_audio_clk *priv;
	int ret;

	priv = devm_kzalloc(&amp;pdev-&gt;dev,
			    struct_size(priv, clk_data.hws,
					MMP2_CLK_AUDIO_NR_CLKS),
			    GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	spin_lock_init(&amp;priv-&gt;lock);
	platform_set_drvdata(pdev, priv);

	priv-&gt;mmio_base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(priv-&gt;mmio_base))
		return PTR_ERR(priv-&gt;mmio_base);

	pm_runtime_enable(&amp;pdev-&gt;dev);
	ret = pm_clk_create(&amp;pdev-&gt;dev);
	if (ret)
		goto disable_pm_runtime;

	ret = pm_clk_add(&amp;pdev-&gt;dev, "audio");
	if (ret)
		goto destroy_pm_clk;

	ret = register_clocks(priv, &amp;pdev-&gt;dev);
	if (ret)
		goto destroy_pm_clk;

	return 0;

destroy_pm_clk:
	pm_clk_destroy(&amp;pdev-&gt;dev);
disable_pm_runtime:
	pm_runtime_disable(&amp;pdev-&gt;dev);

	return ret;
}
</code></pre>

<h2 id="goto-less-alternative-1-nested-ifs"><code>goto</code>-less alternative 1: nested <code>if</code>s</h2>

<p>Drawbacks:</p>
<ul>
  <li>nesting (<a href="https://wiki.c2.com/?ArrowAntiPattern"><em>arrow anti-pattern</em></a>)</li>
  <li>potentially duplicated code (see example function from Linux)</li>
</ul>

<pre><code class="language-c">int *foo(int bar)
{
    int *return_value = NULL;

    if (do_something(bar)) {
        if (init_stuff(bar)) {
            if (prepare_stuff(bar)) {
                return_value = do_the_thing(bar);
            }
            clean_stuff();
        }
        destroy_stuff();
    }
    undo_something();

    return return_value;
}
</code></pre>

<details>
<summary>Example from Linux kernel rewritten</summary>
<div>
    <pre><code class="language-c">static int mmp2_audio_clk_probe(struct platform_device *pdev)
{
    // ...
    pm_runtime_enable(&amp;pdev-&gt;dev);

    ret = pm_clk_create(&amp;pdev-&gt;dev);
    if (!ret) {
        ret = pm_clk_add(&amp;pdev-&gt;dev, "audio");
        if (!ret) {
            ret = register_clocks(priv, &amp;pdev-&gt;dev);
            if (!ret) {
                pm_clk_destroy(&amp;pdev-&gt;dev);
                pm_runtime_disable(&amp;pdev-&gt;dev);
            }
        } else {
            pm_clk_destroy(&amp;pdev-&gt;dev);
            pm_runtime_disable(&amp;pdev-&gt;dev);
        }
    } else {
        pm_runtime_disable(&amp;pdev-&gt;dev);
    }

    return ret; // original was returning 0 explicitly
}
</code></pre>
  </div>
</details>

<p><span></span></p>

<p>And here Microsoft provides us with a <a href="https://learn.microsoft.com/en-us/windows/win32/shell/common-file-dialog#basic-usage">lovely example of such "beautiful" nesting</a>
(<a href="https://web.archive.org/web/20221203064532/https://learn.microsoft.com/en-us/windows/win32/shell/common-file-dialog#basic-usage">archived version</a>).</p>

<h2 id="goto-less-alternative-2-if-not-then-clean"><code>goto</code>-less alternative 2: if not then clean</h2>

<p>Drawbacks:</p>
<ul>
  <li>duplicated code</li>
  <li>multiple exit points</li>
</ul>

<pre><code class="language-c">int *foo(int bar)
{
    int *return_value = NULL;

    if (!do_something(bar)) {
        undo_something();
        return return_value;
    }
    if (!init_stuff(bar)) {
        destroy_stuff();
        undo_something();
        return return_value;
    }
    if (!prepare_stuff(bar)) {
        clean_stuff();
        destroy_stuff();
        undo_something();
        return return_value;
    }

    clean_stuff();
    destroy_stuff();
    undo_something();

    return do_the_thing(bar);
}
</code></pre>

<details>
<summary>Example from Linux kernel rewritten</summary>
<div>
    <pre><code class="language-c">static int mmp2_audio_clk_probe(struct platform_device *pdev)
{
    // ...
    pm_runtime_enable(&amp;pdev-&gt;dev);

    ret = pm_clk_create(&amp;pdev-&gt;dev);
    if (ret) {
        pm_runtime_disable(&amp;pdev-&gt;dev);
        return ret;
    }

    ret = pm_clk_add(&amp;pdev-&gt;dev, "audio");
    if (ret) {
        pm_clk_destroy(&amp;pdev-&gt;dev);
        pm_runtime_disable(&amp;pdev-&gt;dev);
        return ret;
    }

    ret = register_clocks(priv, &amp;pdev-&gt;dev);
    if (ret) {
        pm_clk_destroy(&amp;pdev-&gt;dev);
        pm_runtime_disable(&amp;pdev-&gt;dev);
        return ret;
    }

    return 0;
}
</code></pre>
  </div>
</details>

<h2 id="goto-less-alternative-3-flags"><code>goto</code>-less alternative 3: flags</h2>

<p>Drawbacks:</p>
<ul>
  <li>additional variables</li>
  <li>"cascading" booleans</li>
  <li>potential nesting</li>
  <li>potential complicated boolean expressions</li>
</ul>

<pre><code class="language-c">int *foo(int bar)
{
    int *return_value = NULL;

    bool flag_1 = false;
    bool flag_2 = false;
    bool flag_3 = false;

    flag_1 = do_something(bar);
    if (flag_1) {
        flag_2 = init_stuff(bar);
    }
    if (flag_2) {
        flag_3 = prepare_stuff(bar);
    }
    if (flag_3) {
        return_value = do_the_thing(bar);
    }

    if (flag_3) {
        clean_stuff();
    }
    if (flag_2) {
        destroy_stuff();
    }
    if (flag_1) {
        undo_something();
    }

    return return_value;
}
</code></pre>

<aside>
  <p>Rewrite of <code>mmp2_audio_clk_probe()</code> function doesn't fit clearly into
this case, thus I've put two variants under alternative 3.5 instead.</p>
</aside>

<h2 id="goto-less-alternative-35-so-far-ok-flag"><code>goto</code>-less alternative 3.5: so-far-ok flag</h2>

<pre><code class="language-c">int foo(int bar)
{
    int return_value = 0;
    bool something_done = false;
    bool stuff_inited = false;
    bool stuff_prepared = false;
    bool oksofar = true;

    if (oksofar) {  // this IF is optional (always execs) but included for consistency
        if (do_something(bar)) {
            something_done = true;
        } else {
            oksofar = false;
        }
    }

    if (oksofar) {
        if (init_stuff(bar)) {
            stuff_inited = true;
        } else {
            oksofar = false;
        }
    }

    if (oksofar) {
        if (prepare_stuff(bar)) {
            stuff_prepared = true;
        } else {
            oksofar = false;
        }
    }

    // Do the thing
    if (oksofar) {
        return_value = do_the_thing(bar);
    }

    // Clean up
    if (stuff_prepared) {
        clean_stuff();
    }
    if (stuff_inited) {
        destroy_stuff();
    }
    if (something_done) {
        undo_something();
    }

    return return_value;
}
</code></pre>

<details>
<summary>Example from Linux kernel rewritten</summary>
<div>
    <pre><code class="language-c">static int mmp2_audio_clk_probe(struct platform_device *pdev)
{
    // ...
    pm_runtime_enable(&amp;pdev-&gt;dev);

    bool destroy_pm_clk = false;

    ret = pm_clk_create(&amp;pdev-&gt;dev);
    if (!ret) {
        ret = pm_clk_add(&amp;pdev-&gt;dev, "audio");
        if (ret) {
            destroy_pm_clk = true;
        }
    }
    if (!ret) {
        ret = register_clocks(priv, &amp;pdev-&gt;dev);
        if (ret) {
            destroy_pm_clk = true;
        }
    }

    if (ret) {
        if (destroy_pm_clk) {
            pm_clk_destroy(&amp;pdev-&gt;dev);
        }
        pm_runtime_disable(&amp;pdev-&gt;dev);
        return ret;
    }

    return 0;
}
</code></pre>
  </div>
</details>
<details>
<summary>Example from Linux kernel rewritten</summary>
<div>
    <pre><code class="language-c">static int mmp2_audio_clk_probe(struct platform_device *pdev)
{
    // ...
    pm_runtime_enable(&amp;pdev-&gt;dev);

    bool destroy_pm_clk = false;
    bool disable_pm_runtime = false;

    ret = pm_clk_create(&amp;pdev-&gt;dev);
    if (ret) {
        disable_pm_runtime = true;
    }
    if (!ret) {
        ret = pm_clk_add(&amp;pdev-&gt;dev, "audio");
        if (ret) {
            destroy_pm_clk = true;
        }
    }
    if (!ret) {
        ret = register_clocks(priv, &amp;pdev-&gt;dev);
        if (ret) {
            destroy_pm_clk = true;
        }
    }

    if (destroy_pm_clk) {
        pm_clk_destroy(&amp;pdev-&gt;dev);
    }
    if (disable_pm_runtime) {
        pm_runtime_disable(&amp;pdev-&gt;dev);
    }

    return ret;
}
</code></pre>
  </div>
</details>

<h2 id="goto-less-alternative-4-functions"><code>goto</code>-less alternative 4: functions</h2>

<p>Drawbacks:</p>
<ul>
  <li>More objects (not only new functions, but often also <code>struct</code>s) <br />
<sup title="Things should not be multiplied beyond what is required">
  "Entia non sunt multiplicanda praeter necessitatem"
</sup>
    <ul>
      <li>deeper callstack</li>
    </ul>
  </li>
  <li>often require passing context around
    <ul>
      <li>increase in pointing to pointers</li>
      <li>aforementioned additional <code>struct</code>s</li>
    </ul>
  </li>
  <li>fragmented code
    <ul>
      <li>temptation to needlessly abstract it away</li>
    </ul>
  </li>
</ul>

<pre><code class="language-c">static inline int foo_2(int bar)
{
    int return_value = 0;
    if (prepare_stuff(bar)) {
        return_value = do_the_thing(bar);
    }
    clean_stuff();
    return return_value;
}

static inline int foo_1(int bar)
{
    int return_value = 0;
    if (init_stuff(bar)) {
        return_value = foo_2(bar);
    }
    destroy_stuff();
    return return_value;
}

int foo(int bar)
{
    int return_value = 0;
    if (do_something(bar)) {
        return_value = foo_1(bar);
    }
    undo_something();
    return return_value;
}
</code></pre>

<details>
<summary>Example from Linux kernel rewritten</summary>
<div>
    <pre><code class="language-c">static inline int mmp2_audio_clk_probe_3(struct platform_device* pdev)
{
    int ret = register_clocks(priv, &amp;pdev-&gt;dev);
    if (ret) {
        pm_clk_destroy(&amp;pdev-&gt;dev);
    }
    return ret;
}

static inline int mmp2_audio_clk_probe_2(struct platform_device* pdev)
{
    int ret = pm_clk_add(&amp;pdev-&gt;dev, "audio");
    if (ret) {
        pm_clk_destroy(&amp;pdev-&gt;dev);
    } else {
        ret = mmp2_audio_clk_probe_3(pdev);
    }
    return ret;
}

static inline int mmp2_audio_clk_probe_1(struct platform_device* pdev)
{
    int ret = pm_clk_create(&amp;pdev-&gt;dev);
    if (ret) {
        pm_runtime_disable(&amp;pdev-&gt;dev);
    } else {
        ret = mmp2_audio_clk_probe_2(pdev);
        if (ret) {
            pm_runtime_disable(&amp;pdev-&gt;dev);
        }
    }
    return ret;
}

static int mmp2_audio_clk_probe(struct platform_device* pdev)
{
    // ...
    pm_runtime_enable(&amp;pdev-&gt;dev);

    ret = mmp2_audio_clk_probe_1(pdev);

    return ret;
}
</code></pre>
  </div>
</details>

<h2 id="goto-less-alternative-5-abuse-of-loops"><code>goto</code>-less alternative 5: abuse of loops</h2>

<p>Drawbacks:</p>
<ul>
  <li>half of the drawback of <code>goto</code></li>
  <li>half of the drawback of other alternatives</li>
  <li>none of the benefits of either of the above</li>
  <li>not structural anyway</li>
  <li>creates loop which doesn't loop</li>
  <li>abuse of one language construct just to avoid using the right tool for the job</li>
  <li>less readable</li>
  <li>counter intuitive, confusing</li>
  <li>adds unnecessary nesting</li>
  <li>takes more lines</li>
  <li>don't even think about using a legitimate loop somewhere among this mess</li>
  <li>useless when we wrap it around actual loop or <code>switch</code> statement
("breaking on error" will stop only that one loop/<code>switch</code> instead of whole thing)</li>
</ul>

<pre><code class="language-c">int *foo(int bar)
{
    int *return_value = NULL;

    do {
        if (!do_something(bar)) break;
        do {
            if (!init_stuff(bar)) break;
            do {
                if (!prepare_stuff(bar)) break;
                return_value = do_the_thing(bar);
            } while (0);
            clean_stuff();
        } while (0);
        destroy_stuff();
    } while (0);
    undo_something();

    return return_value;
}
</code></pre>

<details>
<summary>Example from Linux kernel rewritten</summary>
<div>
    <pre><code class="language-c">static int mmp2_audio_clk_probe(struct platform_device *pdev)
{
    // ...
    pm_runtime_enable(&amp;pdev-&gt;dev);

    do {
        ret = pm_clk_create(&amp;pdev-&gt;dev);
        if (ret) break;

        do {
            ret = pm_clk_add(&amp;pdev-&gt;dev, "audio");
            if (ret) break;

            ret = register_clocks(priv, &amp;pdev-&gt;dev);
            if (ret) break;
        } while (0);
        pm_clk_destroy(&amp;pdev-&gt;dev);
    } while (0);
    pm_runtime_disable(&amp;pdev-&gt;dev);

    return ret;
}
</code></pre>
  </div>
</details>

<h1 id="restartretry">Restart/retry</h1>

<p>Common especially on *nix systems when dealing with system calls returning
an error after being interrupted by a signal + setting <code>errno</code> to <code>EINTR</code>
to indicate the it was doing fine and was just interrupted.
Of course, it's not limited to system calls.</p>

<pre><code class="language-c">#include &lt;errno.h&gt;

int main()
{
RETRY_SYSCALL:
    if (some_syscall() == -1) {
        if (errno == EINTR) {
            goto RETRY_SYSCALL;
        }

        // handle real errors
    }

    return 0;
}
</code></pre>

<aside>
  <p>I think in this particular case this one level of additional nesting isn't so
bad, but to be fair, without rewriting it I wouldn't be able to fairly present
the <code>goto</code>-less alternative.</p>

  <details>
<summary>Version with reduced nesting</summary>

<div>
      <pre><code class="language-c">#include &lt;errno.h&gt;

int main()
{
    int res;
RETRY_SYSCALL:
    res = some_syscall();
    if (res == -1 &amp;&amp; errno == EINTR) {
        goto RETRY_SYSCALL;
    }

    if (res) {
        // handle real errors
    }

    return 0;
}
</code></pre>
    </div>
</details>
</aside>

<h2 id="goto-less-alternative-loop"><code>goto</code>-less alternative: loop</h2>

<p>We can of course use a <code>do {} while</code> loop with conditions in <code>while</code>:</p>

<pre><code class="language-c">#include &lt;errno.h&gt;

int main()
{
    int res;
    do {
        res = some_system_call();
    } while (res == -1 &amp;&amp; errno == EINTR);

    if (res == -1) {
        // handle real errors
    }

    return 0;
}
</code></pre>

<p>I think both versions are comparatively readable, but <code>goto</code> has slight advantage
by making it immediately clear the looping is not a desirable situation, while
<code>while</code> loop may be misinterpreted as <a href="https://en.wikipedia.org/wiki/Busy_waiting">waiting loop</a>.</p>

<h2 id="less-trivial-example">Less trivial example</h2>

<p>For those, I'm willing to break the overall monochrome theme of the site and
define colors for syntax highlights. Even with simple parsing done by kramdown
(your code editor would certainty do a better job here), we already notice
labels and <code>goto</code> statements standing out a little from the rest of the code.
Flags on the other hand get lost among other variables.</p>

<style>
.k, .kt  { color: #66d9ef; font-weight:bold }
.c1, .cm { color: #75715e }
.cp { color: #75715e; font-weight: bold }
.o  { color: #f92672; font-weight: bold }
.mi { color: #ae81ff }
.nf { color: #a6e22e }
.p  { color: #f7a000 }
.nl { color: #f4f406 }
</style>

<h3 id="goto-version"><code>goto</code> version</h3>

<div>

  <figure class="highlight"><pre><code class="language-c" data-lang="c"><span class="cp">#include</span> <span class="cpf">&lt;string.h&gt;</span><span class="cp">
</span>
<span class="k">enum</span> <span class="p">{</span>
    <span class="n">PKT_THIS_OPERATION</span><span class="p">,</span>
    <span class="n">PKT_THAT_OPERATION</span><span class="p">,</span>
    <span class="n">PKT_PROCESS_CONDITIONALLY</span><span class="p">,</span>
    <span class="n">PKT_CONDITION_SKIPPED</span><span class="p">,</span>
    <span class="n">PKT_ERROR</span><span class="p">,</span>
    <span class="n">READY_TO_SEND</span><span class="p">,</span>
    <span class="n">NOT_READY_TO_SEND</span>
<span class="p">};</span>

<span class="kt">int</span> <span class="nf">parse_packet</span><span class="p">()</span>
<span class="p">{</span>
    <span class="k">static</span> <span class="kt">int</span> <span class="n">packet_error_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>

    <span class="kt">int</span> <span class="n">packet</span><span class="p">[</span><span class="mi">16</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span> <span class="mi">0</span> <span class="p">};</span>
    <span class="kt">int</span> <span class="n">packet_length</span> <span class="o">=</span> <span class="mi">123</span><span class="p">;</span>
    <span class="kt">_Bool</span> <span class="n">packet_condition</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
    <span class="kt">int</span> <span class="n">packet_status</span> <span class="o">=</span> <span class="mi">4</span><span class="p">;</span>

    <span class="c1">// get packet etc. ...</span>

<span class="nl">REPARSE_PACKET:</span>
    <span class="k">switch</span> <span class="p">(</span><span class="n">packet</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="p">{</span>
    <span class="k">case</span> <span class="n">PKT_THIS_OPERATION</span><span class="p">:</span>
        <span class="k">if</span> <span class="p">(</span><span class="cm">/* problem condition */</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">goto</span> <span class="n">PACKET_ERROR</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="c1">// ... handle THIS_OPERATION</span>
        <span class="k">break</span><span class="p">;</span>

    <span class="k">case</span> <span class="n">PKT_THAT_OPERATION</span><span class="p">:</span>
        <span class="k">if</span> <span class="p">(</span><span class="cm">/* problem condition */</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">goto</span> <span class="n">PACKET_ERROR</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="c1">// ... handle THAT_OPERATION</span>
        <span class="k">break</span><span class="p">;</span>

    <span class="c1">// ...</span>

    <span class="k">case</span> <span class="n">PKT_PROCESS_CONDITIONALLY</span><span class="p">:</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">packet_length</span> <span class="o">&lt;</span> <span class="mi">9</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">goto</span> <span class="n">PACKET_ERROR</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">packet_condition</span> <span class="o">&amp;&amp;</span> <span class="n">packet</span><span class="p">[</span><span class="mi">4</span><span class="p">])</span> <span class="p">{</span>
            <span class="n">packet_length</span> <span class="o">-=</span> <span class="mi">5</span><span class="p">;</span>
            <span class="n">memmove</span><span class="p">(</span><span class="n">packet</span><span class="p">,</span> <span class="n">packet</span><span class="o">+</span><span class="mi">5</span><span class="p">,</span> <span class="n">packet_length</span><span class="p">);</span>
            <span class="k">goto</span> <span class="n">REPARSE_PACKET</span><span class="p">;</span>
        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
            <span class="n">packet</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">PKT_CONDITION_SKIPPED</span><span class="p">;</span>
            <span class="n">packet</span><span class="p">[</span><span class="mi">4</span><span class="p">]</span> <span class="o">=</span> <span class="n">packet_length</span><span class="p">;</span>
            <span class="n">packet_length</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span>
            <span class="n">packet_status</span> <span class="o">=</span> <span class="n">READY_TO_SEND</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="k">break</span><span class="p">;</span>

    <span class="c1">// ...</span>

    <span class="nl">default:</span>
<span class="nl">PACKET_ERROR:</span>
        <span class="n">packet_error_count</span><span class="o">++</span><span class="p">;</span>
        <span class="n">packet_length</span> <span class="o">=</span> <span class="mi">4</span><span class="p">;</span>
        <span class="n">packet</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">PKT_ERROR</span><span class="p">;</span>
        <span class="n">packet_status</span> <span class="o">=</span> <span class="n">READY_TO_SEND</span><span class="p">;</span>
        <span class="k">break</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="c1">// ...</span>

    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span></code></pre></figure>

</div>

<h3 id="goto-less-version"><code>goto</code>-less version</h3>
<div>

  <figure class="highlight"><pre><code class="language-c" data-lang="c"><span class="cp">#include</span> <span class="cpf">&lt;string.h&gt;</span><span class="cp">
</span>
<span class="k">enum</span> <span class="p">{</span>
    <span class="n">PKT_THIS_OPERATION</span><span class="p">,</span>
    <span class="n">PKT_THAT_OPERATION</span><span class="p">,</span>
    <span class="n">PKT_PROCESS_CONDITIONALLY</span><span class="p">,</span>
    <span class="n">PKT_CONDITION_SKIPPED</span><span class="p">,</span>
    <span class="n">PKT_ERROR</span><span class="p">,</span>
    <span class="n">READY_TO_SEND</span><span class="p">,</span>
    <span class="n">NOT_READY_TO_SEND</span>
<span class="p">};</span>

<span class="kt">int</span> <span class="nf">parse_packet</span><span class="p">()</span>
<span class="p">{</span>
    <span class="k">static</span> <span class="kt">int</span> <span class="n">packet_error_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>

    <span class="kt">int</span> <span class="n">packet</span><span class="p">[</span><span class="mi">16</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span> <span class="mi">0</span> <span class="p">};</span>
    <span class="kt">int</span> <span class="n">packet_length</span> <span class="o">=</span> <span class="mi">123</span><span class="p">;</span>
    <span class="kt">_Bool</span> <span class="n">packet_condition</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
    <span class="kt">int</span> <span class="n">packet_status</span> <span class="o">=</span> <span class="mi">4</span><span class="p">;</span>

    <span class="c1">// get packet etc. ...</span>

    <span class="kt">_Bool</span> <span class="n">REPARSE_PACKET</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
    <span class="kt">_Bool</span> <span class="n">PACKET_ERROR</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>

    <span class="k">while</span> <span class="p">(</span><span class="n">REPARSE_PACKET</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">REPARSE_PACKET</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
        <span class="n">PACKET_ERROR</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>

        <span class="k">switch</span> <span class="p">(</span><span class="n">packet</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="p">{</span>
        <span class="k">case</span> <span class="n">PKT_THIS_OPERATION</span><span class="p">:</span>
            <span class="k">if</span> <span class="p">(</span><span class="cm">/* problem condition */</span><span class="p">)</span> <span class="p">{</span>
                <span class="n">PACKET_ERROR</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
                <span class="k">break</span><span class="p">;</span>
            <span class="p">}</span>
            <span class="c1">// ... handle THIS_OPERATION</span>
            <span class="k">break</span><span class="p">;</span>

        <span class="k">case</span> <span class="n">PKT_THAT_OPERATION</span><span class="p">:</span>
            <span class="k">if</span> <span class="p">(</span><span class="cm">/* problem condition */</span><span class="p">)</span> <span class="p">{</span>
                <span class="n">PACKET_ERROR</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
                <span class="k">break</span><span class="p">;</span>
            <span class="p">}</span>
            <span class="c1">// ... handle THAT_OPERATION</span>
            <span class="k">break</span><span class="p">;</span>

            <span class="c1">// ...</span>

        <span class="k">case</span> <span class="n">PKT_PROCESS_CONDITIONALLY</span><span class="p">:</span>
            <span class="k">if</span> <span class="p">(</span><span class="n">packet_length</span> <span class="o">&lt;</span> <span class="mi">9</span><span class="p">)</span> <span class="p">{</span>
                <span class="n">PACKET_ERROR</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
                <span class="k">break</span><span class="p">;</span>
            <span class="p">}</span>
            <span class="k">if</span> <span class="p">(</span><span class="n">packet_condition</span> <span class="o">&amp;&amp;</span> <span class="n">packet</span><span class="p">[</span><span class="mi">4</span><span class="p">])</span> <span class="p">{</span>
                <span class="n">packet_length</span> <span class="o">-=</span> <span class="mi">5</span><span class="p">;</span>
                <span class="n">memmove</span><span class="p">(</span><span class="n">packet</span><span class="p">,</span> <span class="n">packet</span><span class="o">+</span><span class="mi">5</span><span class="p">,</span> <span class="n">packet_length</span><span class="p">);</span>
                <span class="n">REPARSE_PACKET</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
                <span class="k">break</span><span class="p">;</span>
            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                <span class="n">packet</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">PKT_CONDITION_SKIPPED</span><span class="p">;</span>
                <span class="n">packet</span><span class="p">[</span><span class="mi">4</span><span class="p">]</span> <span class="o">=</span> <span class="n">packet_length</span><span class="p">;</span>
                <span class="n">packet_length</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span>
                <span class="n">packet_status</span> <span class="o">=</span> <span class="n">READY_TO_SEND</span><span class="p">;</span>
            <span class="p">}</span>
            <span class="k">break</span><span class="p">;</span>

            <span class="c1">// ...</span>

        <span class="nl">default:</span>
            <span class="n">PACKET_ERROR</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
            <span class="k">break</span><span class="p">;</span>
        <span class="p">}</span>

        <span class="k">if</span> <span class="p">(</span><span class="n">PACKET_ERROR</span><span class="p">)</span> <span class="p">{</span>
            <span class="n">packet_error_count</span><span class="o">++</span><span class="p">;</span>
            <span class="n">packet_length</span> <span class="o">=</span> <span class="mi">4</span><span class="p">;</span>
            <span class="n">packet</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">PKT_ERROR</span><span class="p">;</span>
            <span class="n">packet_status</span> <span class="o">=</span> <span class="n">NOT_READY_TO_SEND</span><span class="p">;</span>
            <span class="k">break</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="c1">// ...</span>

    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span></code></pre></figure>

</div>

<h1 id="common-code-in-switch-statement">Common code in <code>switch</code> statement</h1>

<p>This situation may be a good opportunity to check if the code doesn't need to
be refactored altogether; that being said, sometimes you want to have <code>switch</code>
statement where cases make minor changes then run the same code.</p>

<p>Sure, you could extract the common code into function, but then you need to pass
all the context to it, but that may be inconvenient (for you may need to pass
a lot of parameters or making a dedicated structure, in both cases probably with
pointers) and may increase complexity of the code; in some cases, you may wish
there being only one call to the function instead of multiple.</p>

<p>So why not just jump to the common code?</p>

<pre><code class="language-c">int foo(int v)
{
    // ...
    int something = 0;
    switch (v) {
    case FIRST_CASE:
        something = 2;
        goto common1;
    case SECOND_CASE:
        something = 7;
        goto common1;
    case THIRD_CASE:
        something = 9;
        goto common1;
common1:
        /* code common to FIRST, SECOND and THIRD cases */
        break;

    case FOURTH_CASE:
        something = 10;
        goto common2;
    case FIFTH_CASE:
        something = 42;
        goto common2;
common2:
        /* code common to FOURTH and FIFTH cases */
        break;
    }
    // ...
}
</code></pre>

<h2 id="goto-less-alternative-1-functions"><code>goto</code>-less alternative 1: functions</h2>

<p>Drawbacks:</p>
<ul>
  <li><span title="Things should not be multiplied beyond what is required">"Entia non sunt multiplicanda praeter necessitatem"</span></li>
  <li>reading bottom-up instead of top-bottom</li>
  <li>may require passing context around</li>
</ul>

<pre><code class="language-c">struct foo_context {
    int *something;
    // ...
};

static void common1(struct foo_context ctx)
{
    /* code common to FIRST, SECOND and THIRD cases */
}

static void common2(struct foo_context ctx)
{
    /* code common to FOURTH and FIFTH cases */
}

int foo(int v)
{
    struct foo_context ctx = { NULL };
    // ...
    int something = 0;
    ctx.something = &amp;something;

    switch (v) {
    case FIRST_CASE:
        something = 2;
        common1(ctx);
        break;
    case SECOND_CASE:
        something = 7;
        common1(ctx);
        break;
    case THIRD_CASE:
        something = 9;
        common1(ctx);
        break;

    case FOURTH_CASE:
        something = 10;
        common2(ctx);
        break;
    case FIFTH_CASE:
        something = 42;
        common2(ctx);
        break;
    }
    // ...
}
</code></pre>

<h2 id="goto-less-alternative-2-ifs"><code>goto</code>-less alternative 2: <code>if</code>s</h2>

<p>We can abandon elegance and replace the <code>switch</code> statement with <code>if</code>s</p>

<pre><code class="language-c">int foo(int v)
{
    // ...
    int something = 0;
    if (v == FIRST_CASE || v == SECOND_CASE || v == THIRD_CASE) {
        if (v == FIRST_CASE) {
            something = 2;
        } else if (v == SECOND_CASE) {
            something = 7;
        } else if (v == THIRD_CASE) { // it could be just `else`
            something = 9;
        }
        /* code common to FIRST, SECOND and THIRD cases */
    } else if (v == FOURTH_CASE || v == FIFTH_CASE) {
        if (v == FOURTH_CASE) {
            something = 10;
        } else {
            something = 42;
        }
        /* code common to FOURTH and FIFTH cases */
    }
    // ...
}
</code></pre>

<h2 id="goto-less-alternative-3-interlacing-if-0"><code>goto</code>-less alternative 3: interlacing <code>if (0)</code></h2>

<p>Do... do I really need to comment? <br />
You cannot say "interlacing good" while at the same time claiming "<code>goto</code> bad"!</p>

<pre><code class="language-c">int foo(int v)
{
    // ...
    int something = 0;
    switch (v) {
    case FIRST_CASE:
        something = 2;
      if (0) {
    case SECOND_CASE:
        something = 7;
      }
      if (0) {
    case THIRD_CASE:
        something = 9;
      }
        /* code common to FIRST, SECOND and THIRD cases */
        break;

    case FOURTH_CASE:
        something = 10;
      if (0) {
    case FIFTH_CASE:
        something = 42;
      }
        /* code common to FOURTH and FIFTH cases */
        break;
    }
    // ...
}
</code></pre>

<h2 id="goto-less-alternative-capturing-lambda"><del><code>goto</code>-less alternative: capturing lambda</del></h2>

<p>Yeah, maybe some day...</p>

<h1 id="nested-break-labeled-continue">Nested <code>break</code>, labeled <code>continue</code></h1>

<p>I think this one doesn't require further explanation:</p>

<pre><code class="language-c">#include &lt;stdio.h&gt;

int main()
{
    for (int i = 1; i &lt;= 5; ++i) {
        printf("outer iteration (i): %d\n", i);

        for (int j = 1; j &lt;= 200; ++j) {
            printf("    inner iteration (j): %d\n", j);
            if (j &gt;= 3) {
                break; // breaks from inner loop, outer loop continues
            }
            if (i &gt;= 2) {
                goto outer; // breaks from outer loop, and directly to "Done!"
            }
        }
    }
outer:

    puts("Done!");

    return 0;
}
</code></pre>

<p>We can use <a href="https://beej.us/guide/bgc/html/split/goto.html#labeled-continue">analogous mechanism for <code>continue</code></a>.</p>

<p> </p>

<p><em>Beej's Guide to C Programming</em> has nice example of using this technique alongside the cleanup one:</p>

<blockquote>
  <pre><code class="language-c">    for (...) {
        for (...) {
            while (...) {
                do {
                    if (some_error_condition) {
                        goto bail;
                    }
                    // ...
                } while(...);
            }
        }
    }

bail:
    // Cleanup here
</code></pre>

  <p>Without <code>goto</code>, you'd have to check an error condition
flag in all of the loops to get all the way out.</p>
</blockquote>

<h2 id="breaking-loop-from-inside-a-switch-statement">Breaking loop from inside a <code>switch</code> statement</h2>

<p>Analogically, since <code>switch</code> also utilizes the <code>break</code> keyword,
from inside of it to jump out of a loop:</p>

<pre><code class="language-c">void func(int v)
{
    // ...

    while (1) {
        switch (v) {
        case SOME_V:
            // ...
            break;  // doesn't exit loop
        case STOP_LOOP:
            goto break_while;
        }
    }
break_while:

    // ...
}
</code></pre>

<h1 id="simple-state-machines">Simple state machines</h1>

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 260 130" style="font-family: Times">
  <g fill="#ffffff" stroke="#ffffff">
    <ellipse cx="80" cy="100" rx="10" ry="10" />
    <ellipse cx="160" cy="101" rx="10" ry="10" />
    <ellipse cx="120" cy="41" rx="10" ry="10" />
  </g>

  <g fill="black">
    <text x="73" y="106">A</text>
    <text x="154" y="106.5">B</text>
    <text x="114" y="47">C</text>
  </g>

  <g fill="white">
    <g stroke="white">
      <path d="M 80 91 L 80 51 Q 80 41 90 41 L 105.88 41" fill="none" />
      <path d="M 108.88 41 L 104.88 43 L 105.88 41 L 104.88 39 Z" />

      <path d="M 130 41 L 150 41 Q 160 41 160 51 L 160 86.88" fill="none" />
      <path d="M 160 89.88 L 158 85.88 L 160 86.88 L 162 85.88 Z" />

      <path d="M 152.93 108.07 Q 140 121 120 121 Q 100 121 89.98 110.98" fill="none" />
      <path d="M 87.86 108.86 L 92.1 110.28 L 89.98 110.98 L 89.28 113.1 Z" />

      <path d="M 87.07 93.93 Q 100 81 120 81 Q 140 81 150.02 91.02" fill="none" />
      <path d="M 152.14 93.14 L 147.9 91.72 L 150.02 91.02 L 150.72 88.9 Z" />

      <path d="M 112.93 33.93 Q 113 11 120 11 Q 127 11 127.06 29.81" fill="none" />
      <path d="M 127.00 32.81 L 125.06 28.82 L 127.06 29.81 L 129.06 28.8 Z" />

      <path d="M 80 111 Q 80 131 70 126 Q 60 121 70.02 110.98" fill="none" />
      <path d="M 72.14 108.86 L 70.72 113.1 L 70.02 110.98 L 67.9 110.28 Z" />

      <path d="M 160 111 Q 160 131 170 126 Q 180 121 169.98 110.98" fill="none" />
      <path d="M 167.86 108.86 L 172.1 110.28 L 169.98 110.98 L 169.28 113.1 Z" />

      <path d="M 30 91 L 66 100" fill="none" />
      <path d="M 68.92 100.73 L 64.55 101.7 L 66 100 L 65.52 97.82 Z" />

      <path d="M 170 101 L 206 92" fill="none" />
      <path d="M 208.92 91.27 L 205.52 94.18 L 206 92 L 204.55 90.3 Z" />
    </g>

    <text x="16" y="90">S</text>
    <text x="214" y="90">F</text>

    <g font-size="0.7em">
      <text x="117" y="7">x</text>

      <text x="70" y="55">y</text>
      <text x="165" y="55">z</text>

      <text x="117" y="75">x</text>
      <text x="117" y="115">y</text>

      <text x="55" y="125">z</text>
      <text x="180" y="125">x</text>

      <text x="180" y="90" font-style="italic">nul</text>
    </g>
  </g>
</svg>

<p> </p>

<p>The following is a 1:1, not far from <strong>verbatim mathematical notation</strong>,
implementation of the above automata:</p>

<pre><code class="language-c">_Bool machine(const char *c)
{
qA:
    switch (*(c++)) {
    case 'x': goto qB;
    case 'y': goto qC;
    case 'z': goto qA;
    default: goto err;
    }

qB:
    switch (*(c++)) {
    case 'x': goto qB;
    case 'y': goto qA;
    case '\0': goto F;
    default: goto err;
    }

qC:
    switch (*(c++)) {
    case 'x': goto qC;
    case 'z': goto qB;
    default: goto err;
    }

F:
    return true;

err:
    return false;
}
</code></pre>

<h1 id="jumping-into-event-loop">Jumping into event loop</h1>

<p>Yeah, yeah, I know jumping <em>into</em> warrants at least a raised eyebrow.
That being said, there are cases when you may want to do just that.</p>

<p>Here in first iteration program skips increasing variable and goes straight
to allocation. Each following iteration executes code as written, ignoring
completely the label relevant only for the first run; so you do too during
analysis.</p>

<pre><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;fancy_alloc.h&gt;

int main()
{
    int *buf = NULL;
    size_t pos = 0;
    size_t sz = 8;

    int *temp;

    goto ALLOC;
    do {
        if (pos &gt; sz) { // resize array
            sz *= 2;
ALLOC:      temp = arrayAllocSmart(buf, sz, pos);
            /* check for errors */
            buf = temp;
        }

        /* do something with buf */
    } while (checkQuit());

    return 0;

    /* handle errors ... */
}
</code></pre>

<h3 id="goto-less-alternative-1-guard-flag"><code>goto</code>-less alternative 1: guard flag</h3>

<p>It probably says more about the state of my sleep deprived brain than anything
else, but I actually managed to make an honest, very dumb mistake in this
simple snippet. I didn't notice until after examining the assembly output
and seeing way less instructions than expected. Since it's simple, yet quite
severe in consequences, I decided to leave it as an exercise for the reader
to spot the bug (should be easy since you already know about its existence).</p>

<p>The drawbacks as per usual: nesting and keeping track of flags.</p>

<pre><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;fancy_alloc.h&gt;

int main()
{
    int *buf = NULL;
    size_t pos = 0;
    size_t sz = 8;

    int ret = 0

    _Bool firstIter = true;

    do {
        if (pos &gt; sz || firstIter) { // resize array
            if (!firstIter) {
                sz *= 2;
                firstIter = false;
            }

            int *temp = arrayAllocSmart(buf, sz, pos);
            /* handle errors ... */
            buf = temp;
        }

        /* do something with buf */
    } while (checkQuit());

    return 0;
}
</code></pre>

<h3 id="goto-less-alternative-2-code-duplication"><code>goto</code>-less alternative 2: code duplication</h3>

<p>The drawback is obvious, thus no further comment.</p>

<pre><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;fancy_alloc.h&gt;

int main()
{
    size_t pos = 0;
    size_t sz = 8;

    int *buf = arrayAllocSmart(NULL, sz, pos);
    /* handle errors ... */

    do {
        if (pos &gt; sz) { // resize array
            sz *= 2;
            int *temp = arrayAllocSmart(buf, sz, pos);
            /* handle errors ... */
            buf = temp;
        }

        /* do something with buf */
    } while (checkQuit());

    return 0;
}
</code></pre>

<h1 id="optimizations">Optimizations</h1>

<p>This section is purely informative, just to appear on list as to mark the
existence of such use-case. Giving an example for this is not so easy, either
from legal or conceptual standpoint as most of them apply only in very narrow
situations, not rarely bordering on micro-optimizing.</p>

<aside>
  <p>Often extensions like <a href="https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html">computed <code>goto</code></a> are used.</p>
</aside>

<p>Beej shows <a href="https://beej.us/guide/bgc/html/split/goto.html#tail-call-optimization">tail call optimization</a>
as an example in his book. Unfortunately (from educational standpoint! otherwise, it's a great thing)
modern compilers easily optimize something as simple as factorial to the very same assembly which we get
using the <code>goto</code> optimization. On the other hand, not everybody is blessed with modern, optimizing compiler...</p>

<h1 id="structured-programming-with-go-to-statements"><a href="https://dl.acm.org/doi/epdf/10.1145/356635.356640"><em>Structured Programming with <strong>go to</strong> Statements</em></a></h1>

<p>Read at:
  <a href="https://dl.acm.org/doi/epdf/10.1145/356635.356640">[ACM Digital Library]</a>
  <a href="https://pic.plover.com/knuth-GOTO.pdf">[PDF]</a>
  <a href="http://www.kohala.com/start/papers.others/knuth.dec74.html">[HTML]</a></p>

<p>If I started from Dijkstra, it's only natural I need to conclude with Knuth. <br />
Almost anybody who says anything positive about <code>goto</code> refers to this paper.
And rightfully so! To this day it's one of most comprehensive resources
on the topic (it's a go to resource about <code>goto</code>). Perhaps some examples
are quite dated, some concerns less crucial today than back in the day,
but nevertheless it's an excellent read.</p>

<blockquote>
  <p>One thing we haven't spelled out clearly, however, is what makes some
<strong>go to</strong>'s bad and others acceptable. The reason is that we've really
been directing our attention to the wrong issue, to the objective question of
<strong>go to</strong> elimination instead of the important subjective question of
program structure. In the words of John Brown, "The act of focusing our
mightiest intellectual resources on the elusive goal of <strong>go to</strong>-less
programs has helped us get our minds off all those really tough and possibly
unresolvable problems and issues with which today's professional programmer
would otherwise have to grapple." By writing this long article I don't want
to add fuel to the controversy about go to elimination, since that topic
has already assumed entirely too much significance; my goal is to lay that
controversy to rest, and to help direct the discussion towards more fruitful
channels.</p>
</blockquote>]]></content><author><name>Jorenar</name></author><summary type="html"><![CDATA[gotophobia -- fear of goto statement; usually caused by a lack of context, and misunderstanding of stories from dark ages of programming. Programmers with gotophobia tend to make their code less readable just to avoid using goto.]]></summary></entry><entry><title type="html">Short list of C esoterica</title><link href="https://jorenar.com/c-esoterica" rel="alternate" type="text/html" title="Short list of C esoterica" /><published>2023-02-19T00:00:00+00:00</published><updated>2023-02-19T00:00:00+00:00</updated><id>https://jorenar.com/c-esoterica</id><content type="html" xml:base="https://jorenar.com/c-esoterica"><![CDATA[<p>There are some tricks, quirks, and features which seems to throw even
experienced developers off the track. Thus, I periodically revisit this
blogpost, to do a sloppy job of gathering them in an unordered list with
some short explanations, examples, quotes, or references.</p>

<p>Obviously though, I'm not gonna list absolutely everything, for facts like
<em>"function <code>nan()</code> cannot set <code>errno</code> as it shall behave like <code>strtod()</code> in
certain cases"</em> ain't so much fun.</p>

<aside>
  <p><strong>ATTENTION</strong><br />
Something being listed here does <span style="color:yellow"><strong><em>not</em></strong></span>
automatically mean encouragement <strong>nor</strong> discouragement to use it! Some of
those should <span style="color:red"><strong><em>never</em></strong></span> be brought outside
lists like this, while some of them are <span style="color:green"><strong>incredibly
useful</strong></span>! I'm putting faith into readers' <em>common sense</em>.</p>
</aside>

<p><strong>Resources:</strong></p>
<ul>
  <li><a href="https://www.youtube.com/watch?v=w3_e9vZj7D8">Advanced C: The UB and optimizations that trick good programmers.</a></li>
  <li><a href="https://graphics.stanford.edu/~seander/bithacks.html">Bit Twiddling Hacks</a></li>
  <li><a href="http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf">C99 with Technical corrigenda TC1, TC2, and TC3 included</a></li>
  <li><a href="http://www.pvv.org/~oma/DeepC_slides_oct2011.pdf">Deep C (and C++) <em>by Olve Maudal and Jon Jagger</em></a></li>
  <li><a href="https://stackoverflow.com/q/132241/10247460">Hidden features of C - Stack Overflow</a></li>
  <li><a href="https://blog.robertelder.org/switch-statements-statement-expressions/">How to Get Fired Using Switch Statements &amp; Statement Expressions</a></li>
  <li><a href="https://www.reddit.com/r/C_Programming/comments/mqk338/interesting_ways_to_use_c/">Interesting ways to use C? : r/C_Programming</a></li>
  <li><a href="https://d3s.mff.cuni.cz/legacy/~holub/c_features.html">Lesser known C features</a></li>
  <li><a href="https://gist.github.com/shakna-israel/4fd31ee469274aa49f8f9793c3e71163#lets-destroy-c">Let's Destroy C</a></li>
  <li><a href="https://github.com/Chi-Iroh/Lets-Talk-About-C-Quirks">Let's Talk About C Quirks!</a></li>
  <li><a href="https://news.ycombinator.com/item?id=33680239">Mildly interesting quirks of C | Hacker News</a></li>
  <li><a href="http://www.robertgamble.net/2011/05/how-well-do-you-know-c.html">Rob's Programming Blog: How Well Do You Know C?</a></li>
  <li><a href="https://docs.google.com/presentation/d/1h49gY3TSiayLMXYmRMaAEMl05FaJ-Z6jDOWOz3EsqqQ">Some dark corners of C</a></li>
  <li><a href="https://jadlevesque.github.io/PPMP-Iceberg/">The Preprocessor Iceberg Meme</a></li>
  <li><a href="https://www.reddit.com/r/C_Programming/comments/pxgyee/what_your_weirdest_c_feature/">What your weirdest C feature? : r/C_Programming</a></li>
</ul>

<p> </p>

<ul id="markdown-toc">
  <li><a href="#variables-declaration-in-parentheses" id="markdown-toc-variables-declaration-in-parentheses">Variables declaration in parentheses</a></li>
  <li><a href="#array-pointers" id="markdown-toc-array-pointers">Array pointers</a></li>
  <li><a href="#comma-operator" id="markdown-toc-comma-operator">Comma operator</a></li>
  <li><a href="#digraphs-trigraphs-and-alternative-tokens" id="markdown-toc-digraphs-trigraphs-and-alternative-tokens">Digraphs, trigraphs and alternative tokens</a></li>
  <li><a href="#designated-initializer" id="markdown-toc-designated-initializer">Designated initializer</a></li>
  <li><a href="#compound-literals" id="markdown-toc-compound-literals">Compound literals</a></li>
  <li><a href="#compound-literals-are-lvalues" id="markdown-toc-compound-literals-are-lvalues">Compound literals are lvalues</a></li>
  <li><a href="#escaping-shadowing" id="markdown-toc-escaping-shadowing">Escaping shadowing</a></li>
  <li><a href="#multi-character-constants" id="markdown-toc-multi-character-constants">Multi-character constants</a></li>
  <li><a href="#bit-fields" id="markdown-toc-bit-fields">Bit fields</a></li>
  <li><a href="#0-bit-fields" id="markdown-toc-0-bit-fields">0 bit fields</a></li>
  <li><a href="#volatile-type-qualifier" id="markdown-toc-volatile-type-qualifier"><code>volatile</code> type qualifier</a></li>
  <li><a href="#restrict-type-qualifier" id="markdown-toc-restrict-type-qualifier"><code>restrict</code> type qualifier</a></li>
  <li><a href="#register-type-qualifier" id="markdown-toc-register-type-qualifier"><code>register</code> type qualifier</a></li>
  <li><a href="#flexible-array-member" id="markdown-toc-flexible-array-member">Flexible array member</a></li>
  <li><a href="#n-format-specifier" id="markdown-toc-n-format-specifier"><code>%n</code> format specifier</a></li>
  <li><a href="#-minimum-field-width-format-specifier" id="markdown-toc--minimum-field-width-format-specifier"><code>%.*</code> (minimum field width) format specifier</a></li>
  <li><a href="#other-less-known-format-specifiers" id="markdown-toc-other-less-known-format-specifiers">Other less known format specifiers</a></li>
  <li><a href="#interlacing-syntactic-constructs" id="markdown-toc-interlacing-syntactic-constructs">Interlacing syntactic constructs</a></li>
  <li><a href="#---operator" id="markdown-toc----operator"><code>--&gt;</code> "operator"</a></li>
  <li><a href="#idxarr" id="markdown-toc-idxarr"><code>idx[arr]</code></a></li>
  <li><a href="#negative-array-indexes" id="markdown-toc-negative-array-indexes">Negative array indexes</a></li>
  <li><a href="#constant-string-concatenation" id="markdown-toc-constant-string-concatenation">Constant string concatenation</a></li>
  <li><a href="#backslash-line-splicing" id="markdown-toc-backslash-line-splicing">Backslash line splicing</a></li>
  <li><a href="#using--and--as-conditionals" id="markdown-toc-using--and--as-conditionals">Using <code>&amp;&amp;</code> and <code>||</code> as conditionals</a></li>
  <li><a href="#compile-time-assumption-checking-using-enums" id="markdown-toc-compile-time-assumption-checking-using-enums">Compile time assumption checking using <code>enum</code>s</a></li>
  <li><a href="#ad-hoc-struct-declaration-in-the-return-type-of-a-function" id="markdown-toc-ad-hoc-struct-declaration-in-the-return-type-of-a-function">Ad hoc <code>struct</code> declaration in the return type of a function</a></li>
  <li><a href="#nested-struct-definition-is-not-kept-nested" id="markdown-toc-nested-struct-definition-is-not-kept-nested">"Nested" <code>struct</code> definition is not kept nested</a></li>
  <li><a href="#flat-initializer-lists" id="markdown-toc-flat-initializer-lists">Flat initializer lists</a></li>
  <li><a href="#implicit-casting-of-void-pointers" id="markdown-toc-implicit-casting-of-void-pointers">Implicit casting of <code>void</code> pointers</a></li>
  <li><a href="#static-array-indices-in-function-parameter-declarations" id="markdown-toc-static-array-indices-in-function-parameter-declarations">Static array indices in function parameter declarations</a></li>
  <li><a href="#macro-overloading-by-argument-list-length" id="markdown-toc-macro-overloading-by-argument-list-length">Macro Overloading by Argument List Length</a></li>
  <li><a href="#typedef-syntax-is-like-other-specifiers" id="markdown-toc-typedef-syntax-is-like-other-specifiers"><code>typedef</code> syntax is like other specifiers</a></li>
  <li><a href="#function-types" id="markdown-toc-function-types">Function types</a></li>
  <li><a href="#the-oddities-of-relationship-between-function-designators-and-pointers" id="markdown-toc-the-oddities-of-relationship-between-function-designators-and-pointers">The oddities of relationship between function designators and pointers</a></li>
  <li><a href="#x-macros" id="markdown-toc-x-macros">X-Macros</a></li>
  <li><a href="#x-files" id="markdown-toc-x-files">X-Files</a></li>
  <li><a href="#named-function-parameters" id="markdown-toc-named-function-parameters">Named function parameters</a></li>
  <li><a href="#combining-default-named-and-positional-arguments" id="markdown-toc-combining-default-named-and-positional-arguments">Combining default, named and positional arguments</a></li>
  <li><a href="#abusing-unions-for-grouping-things-into-namespaces" id="markdown-toc-abusing-unions-for-grouping-things-into-namespaces">Abusing unions for grouping things into namespaces</a></li>
  <li><a href="#unity-builds" id="markdown-toc-unity-builds">Unity builds</a></li>
  <li><a href="#matching-character-classes-with-sscanf" id="markdown-toc-matching-character-classes-with-sscanf">Matching character classes with <code>sscanf()</code></a></li>
  <li><a href="#garbage-collector" id="markdown-toc-garbage-collector">Garbage collector</a></li>
  <li><a href="#cosmopolitan-libc" id="markdown-toc-cosmopolitan-libc">Cosmopolitan Libc</a></li>
  <li><a href="#inline-assembly" id="markdown-toc-inline-assembly">Inline assembly</a></li>
  <li><a href="#coroutines" id="markdown-toc-coroutines">Coroutines</a></li>
  <li><a href="#evaluate-sizeof-at-compile-time-by-causing-duplicate-case-error" id="markdown-toc-evaluate-sizeof-at-compile-time-by-causing-duplicate-case-error">Evaluate <code>sizeof</code> at compile time by causing duplicate case error</a></li>
  <li><a href="#detecting-constant-expressions" id="markdown-toc-detecting-constant-expressions">Detecting constant expressions</a></li>
  <li><a href="#object-oriented-programming" id="markdown-toc-object-oriented-programming">Object Oriented Programming</a></li>
  <li><a href="#safeish-variadic-functions" id="markdown-toc-safeish-variadic-functions">Safe(ish) variadic functions</a></li>
  <li><a href="#metaprogramming" id="markdown-toc-metaprogramming">Metaprogramming</a></li>
  <li><a href="#preprocessor-is-a-language-of-its-own" id="markdown-toc-preprocessor-is-a-language-of-its-own">Preprocessor is a language of its own</a></li>
  <li><a href="#ccan" id="markdown-toc-ccan">CCAN</a></li>
  <li><a href="#function-pointers-to-match-arrays-in-_generic" id="markdown-toc-function-pointers-to-match-arrays-in-_generic">Function pointers to match arrays in <code>_Generic</code></a></li>
  <li><a href="#polyglot-files" id="markdown-toc-polyglot-files">Polyglot files</a></li>
  <li><a href="#forward-declaration-is-optional" id="markdown-toc-forward-declaration-is-optional">Forward declaration is optional</a></li>
</ul>

<h2 id="variables-declaration-in-parentheses">Variables declaration in parentheses</h2>

<p>Names of variables can be wrapped in parentheses in declarations:</p>

<pre><code class="language-c">int (v);
void (*p);
float (ar1)[16];
double (ar1[8]);
int x, (*y), (z);
</code></pre>

<h2 id="array-pointers">Array pointers</h2>

<p>Decay-to-pointer makes regular pointers to array usually not needed:</p>
<pre><code class="language-c">int arr[10];

int *ap0 = arr;        // array decay-to-pointer
// ap0[2] = ...

int (*ap1)[10] = &amp;arr; // proper pointer to array
// (*ap1)[2] = ...
</code></pre>

<p>But ability to allocate a big multi-dimensional array on heap is nice:</p>
<pre><code class="language-c">int (*ap3)[90000][90000] = malloc(sizeof *ap3);
</code></pre>

<p>With pointers even VLA can find its use (<a href="/blog/vla-usecases">more here</a>):</p>
<pre><code class="language-c">int (*ap4)[n] = malloc(sizeof *ap4);
</code></pre>

<h2 id="comma-operator">Comma operator</h2>

<p>The comma operator is used to separate two or more expressions that are
included where only one expression is expected. When the set of expressions
has to be evaluated for a value, only the right-most expression is considered.</p>

<p>For example: <code>b = (a=3, a+2);</code> -- this code would firstly assign value 3
to <code>a</code>, and then <code>a+2</code> would be assigned to variable <code>b</code>. So, at the end,
<code>b</code> would contain value 5 while variable <code>a</code> would be 3.</p>

<p>On Wikipedia we can find <a href="https://en.wikipedia.org/wiki/Comma_operator#Examples">few more examples</a>.</p>

<h2 id="digraphs-trigraphs-and-alternative-tokens">Digraphs, trigraphs and alternative tokens</h2>

<p>C code may not be portable, but the language itself is probably more portable
than any other; there are system using e.g. EBCDIC encoding instead of ASCII,
to support them C has digraphs and trigraphs -- multi-character sequences
treated by the compiler as other characters.</p>

<table>
  <thead>
    <tr>
      <th style="text-align: center">Digraph</th>
      <th style="text-align: center"> </th>
      <th> </th>
      <th style="text-align: center">Trigraph</th>
      <th style="text-align: center"> </th>
      <th> </th>
      <th style="text-align: center">iso646.h</th>
      <th style="text-align: center"> </th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: center"><code>&lt;:</code></td>
      <td style="text-align: center"><code>[</code></td>
      <td> </td>
      <td style="text-align: center"><code>??=</code></td>
      <td style="text-align: center"><code>#</code></td>
      <td> </td>
      <td style="text-align: center"><code>and</code></td>
      <td style="text-align: center"><code>&amp;&amp;</code></td>
    </tr>
    <tr>
      <td style="text-align: center"><code>:&gt;</code></td>
      <td style="text-align: center"><code>]</code></td>
      <td> </td>
      <td style="text-align: center"><code>??(</code></td>
      <td style="text-align: center"><code>[</code></td>
      <td> </td>
      <td style="text-align: center"><code>and_eq</code></td>
      <td style="text-align: center"><code>&amp;=</code></td>
    </tr>
    <tr>
      <td style="text-align: center"><code>&lt;%</code></td>
      <td style="text-align: center"><code>{</code></td>
      <td> </td>
      <td style="text-align: center"><code>??/</code></td>
      <td style="text-align: center"><code>\</code></td>
      <td> </td>
      <td style="text-align: center"><code>bitand</code></td>
      <td style="text-align: center"><code>&amp;</code></td>
    </tr>
    <tr>
      <td style="text-align: center"><code>%&gt;</code></td>
      <td style="text-align: center"><code>}</code></td>
      <td> </td>
      <td style="text-align: center"><code>??)</code></td>
      <td style="text-align: center"><code>]</code></td>
      <td> </td>
      <td style="text-align: center"><code>bitor</code></td>
      <td style="text-align: center"><code>|</code></td>
    </tr>
    <tr>
      <td style="text-align: center"><code>%:</code></td>
      <td style="text-align: center"><code>#</code></td>
      <td> </td>
      <td style="text-align: center"><code>??'</code></td>
      <td style="text-align: center"><code>^</code></td>
      <td> </td>
      <td style="text-align: center"><code>compl</code></td>
      <td style="text-align: center"><code>~</code></td>
    </tr>
    <tr>
      <td style="text-align: center"><code>%:%:</code></td>
      <td style="text-align: center"><code>##</code></td>
      <td> </td>
      <td style="text-align: center"><code>??&lt;</code></td>
      <td style="text-align: center"><code>{</code></td>
      <td> </td>
      <td style="text-align: center"><code>not</code></td>
      <td style="text-align: center"><code>!</code></td>
    </tr>
    <tr>
      <td style="text-align: center">--------</td>
      <td style="text-align: center">-----------</td>
      <td> </td>
      <td style="text-align: center"><code>??!</code></td>
      <td style="text-align: center"><code>|</code></td>
      <td> </td>
      <td style="text-align: center"><code>not_eq</code></td>
      <td style="text-align: center"><code>!=</code></td>
    </tr>
    <tr>
      <td style="text-align: center">--------</td>
      <td style="text-align: center">-----------</td>
      <td> </td>
      <td style="text-align: center"><code>??&gt;</code></td>
      <td style="text-align: center"><code>}</code></td>
      <td> </td>
      <td style="text-align: center"><code>or</code></td>
      <td style="text-align: center"><code>||</code></td>
    </tr>
    <tr>
      <td style="text-align: center">--------</td>
      <td style="text-align: center">-----------</td>
      <td> </td>
      <td style="text-align: center"><code>??-</code></td>
      <td style="text-align: center"><code>~</code></td>
      <td> </td>
      <td style="text-align: center"><code>or_eq</code></td>
      <td style="text-align: center"><code>|=</code></td>
    </tr>
    <tr>
      <td style="text-align: center">--------</td>
      <td style="text-align: center">-----------</td>
      <td> </td>
      <td style="text-align: center">--------</td>
      <td style="text-align: center">-----------</td>
      <td> </td>
      <td style="text-align: center"><code>xor</code></td>
      <td style="text-align: center"><code>^</code></td>
    </tr>
    <tr>
      <td style="text-align: center">--------</td>
      <td style="text-align: center">-----------</td>
      <td> </td>
      <td style="text-align: center">--------</td>
      <td style="text-align: center">-----------</td>
      <td> </td>
      <td style="text-align: center"><code>xor_eq</code></td>
      <td style="text-align: center"><code>^=</code></td>
    </tr>
  </tbody>
</table>

<aside>
  <p>Despite there being small opposition, the Committee
decided to remove support for trigraphs since C23.</p>
</aside>

<ul>
  <li><a href="https://blog.yossarian.net/2015/04/02/Digraphs-And-Trigraphs">Mini-post: Digraphs and Trigraphs | ENOSUCHBLOG</a></li>
  <li><a href="https://en.wikipedia.org/wiki/C_alternative_tokens">C alternative tokens - Wikipedia</a></li>
  <li><a href="https://stackoverflow.com/q/432443/10247460">Why are there digraphs in C and C++? - Stack Overflow</a></li>
  <li><a href="https://stackoverflow.com/q/1234582/10247460">Purpose of Trigraph sequences in C++?</a></li>
  <li><a href="https://www.lysator.liu.se/c/na1.html">A brief description of Normative Addendum 1</a></li>
</ul>

<h2 id="designated-initializer">Designated initializer</h2>

<p>These allow you to specify which elements of an object (array, structure, union)
are to be initialized by the values following. The order does not matter!</p>

<pre><code class="language-c">struct Foo {
    int x, y;
    const char *bar;
};

void f(void)
{
    int arr[] = { 1, 2, [5] = 9, [9] = 5, [8] = 8 };

    struct Foo f = { .y = 23, .bar = "barman", .x = -38 };

    struct Foo arr[] = {
        [10] = {      8,  8,      9 },
         [8] = {      1,  8,   bar3 },
        [12] = { .x = 9,     .z = 8 },
    };

    struct {
        int sec, min, hour, day, mon, year;
    } z = { 
        .day = 31, 12, 2014, 
        .sec = 30, 15, 17
    }; // initializes z to { 30, 15, 17,  31, 12, 2014 }
}
</code></pre>

<ul>
  <li><a href="https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html">Designated Inits (Using the GNU Compiler Collection (GCC))</a></li>
  <li><a href="https://www.ibm.com/docs/en/zos/2.5.0?topic=initializers-designated-aggregate-types-c-only">Designated initializers for aggregate types (C only) - IBM Documentation</a></li>
  <li><a href="https://stackoverflow.com/q/47202557/10247460">What is a designated initializer in C? - Stack Overflow</a></li>
</ul>

<h2 id="compound-literals">Compound literals</h2>

<p>A compound literal looks like a cast of a brace-enclosed initializer list.
Its value is an object of the type specified in the cast, containing the
elements specified in the initializer.</p>

<pre><code class="language-c">#include &lt;stdio.h&gt;

struct Foo { int x, y; };

void bar(struct Foo p)
{
    printf("%d, %d", p.x, p.y);
}

int main(void)
{
    bar((struct Foo){2, 3});
    return 0;
}
</code></pre>

<ul>
  <li><a href="https://gcc.gnu.org/onlinedocs/gcc/Compound-Literals.html">Compound Literals (Using the GNU Compiler Collection (GCC))</a></li>
</ul>

<h2 id="compound-literals-are-lvalues">Compound literals are lvalues</h2>

<pre><code class="language-c">(struct Foo){};
((struct Foo){}).x = 4;
&amp;(struct Foo){};
func(&amp;(struct Foo){.x = 2});
</code></pre>

<p>Even if you already knew about compound literals, there's a high chance you've
never consciously noticed them being lvalues. And it's important, because when
a value is an lvalue, we can get its address (and e.g. pass it to function).</p>

<h2 id="escaping-shadowing">Escaping shadowing</h2>

<p>The following code will return 42, not 3840!</p>

<pre><code class="language-c">int x = 42;

int func() {
    int x = 3840;
    {
        extern int x;
        return x;
    }
}
</code></pre>

<h2 id="multi-character-constants">Multi-character constants</h2>

<p>They are implementation dependent and even the standard itself to usually
best avoid them. That being said, using them as self-documenting <code>enum</code>s
can be quite handy when you may need to deal with raw memory dumps later on.</p>

<pre><code class="language-c">enum state {
    waiting = 'WAIT',
    running = 'RUN!',
    stopped = 'STOP',
};
</code></pre>

<p>For example, on my machine I could localize <code>'WAIT'</code> like here:</p>
<pre><code>00001120: c3 66 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00  .ff...........@.
00001130: f3 0f 1e fa e9 67 ff ff ff 55 48 89 e5 48 83 ec  .....g...UH..H..
00001140: 10 c7 45 fc <mark>54 49 41 57</mark> 8b 45 fc 89 c6 48 8d 05  ..E.<mark>TIAW</mark>.E...H..
00001150: b0 0e 00 00 48 89 c7 b8 00 00 00 00 e8 cf fe ff  ....H...........
00001160: ff b8 00 00 00 00 c9 c3 f3 0f 1e fa 48 83 ec 08  ............H...</code></pre>

<h2 id="bit-fields">Bit fields</h2>

<p>Declares a member with explicit width, in bits. Adjacent bit field members may
be packed to share and straddle the individual bytes.</p>

<pre><code class="language-c">struct cat {
    unsigned int legs  : 3;  // 3 bits for legs  (0-4 fit in 3 bits)
    unsigned int lives : 4;  // 4 bits for lives (0-9 fit in 4 bits)
};
</code></pre>

<ul>
  <li><a href="https://en.cppreference.com/w/c/language/bit_field">Bit fields - cppreference.com</a></li>
  <li><a href="https://en.wikipedia.org/wiki/Bit_field">Bit field - Wikipedia</a></li>
  <li><a href="https://stackoverflow.com/q/24933242/10247460">When to use bit-fields in C - Stack Overflow</a></li>
</ul>

<h2 id="0-bit-fields">0 bit fields</h2>

<ul>
  <li><a href="https://stackoverflow.com/q/45916894/10247460">What does an unnamed zero length bit-field mean in C? - Stack Overflow</a></li>
  <li><a href="https://stackoverflow.com/q/4297095/10247460">Practical Use of Zero-Length Bitfields - Stack Overflow</a></li>
  <li><a href="https://www.ibm.com/docs/en/xcafbg/9.0.0?topic=SS3KZ4_9.0.0/com.ibm.xlcpp9.bg.doc/proguide/calgnbit.html">IBM Documentation - IBM Documentation</a></li>
  <li><a href="https://en.cppreference.com/w/c/language/bit_field">Bit fields - cppreference.com</a></li>
</ul>

<p><span></span></p>

<p>Description from <a href="https://developer.arm.com/documentation/ka004594/latest">Arm Compiler 6 docs</a>:</p>

<blockquote>
  <p>A zero-length bit-field can be used to make the following changes:</p>
  <ul>
    <li>Creates a boundary between any bit-fields before the zero-length bit-field
and any bit-fields after the zero-length bit-field. Any bit-fields on
opposite sides of the boundary are treated as non-overlapping memory
locations. This has a consequence for C and C++ programs. The C and C++
standards require both load and store accesses to a bit-field on one side
of the boundary to not access any bit-fields on the other side of the boundary.</li>
    <li>Insert padding to align any bit-fields after the zero-length bit-field to
the next available natural boundary based on the type of the zero-length
bit-field. For example, <code>char:0</code> can be used to align to the next available
byte boundary, and <code>int:0</code> can be used to align to the next available word boundary.</li>
  </ul>
</blockquote>

<p>An example taken from the <a href="https://stackoverflow.com/a/26725041/10247460">SO answer</a> (with slight changes):</p>

<blockquote>
  <pre><code class="language-c">struct bar {
    unsigned char x : 5;
    unsigned short  : 0;
    unsigned char y : 7;
}
</code></pre>

  <p>The above in memory would look like this (assuming 16-bit <code>short</code>, ignoring endian):</p>

  <pre><code>char pad pad      short boundary
 |    |   |        |
 v    v   v        v
 xxxxx000 00000000 yyyyyyy0
</code></pre>

  <p>The zero-length bit field causes the position to move to next <code>short</code> boundary
(or: be placed on the nearest natural alignment for the target platform).
We defined <code>short</code> to be 16-bit, so 16 minus 5 gives 11 bits of padding.</p>
</blockquote>

<h2 id="volatile-type-qualifier"><code>volatile</code> type qualifier</h2>

<p>This qualifier tells the compiler that a variable may be accessed by other
means than the current code (e.g. we are dealing with MMIO device), thus to
not optimize away reads and writes to this resource.</p>

<p> </p>

<ul>
  <li><a href="https://stackoverflow.com/q/246127/10247460">Why is volatile needed in C? - Stack Overflow</a></li>
  <li><a href="https://www.youtube.com/watch?v=w3_e9vZj7D8">Advanced C: The UB and optimizations that trick good programmers.</a></li>
  <li><a href="https://en.cppreference.com/w/c/language/volatile">volatile type qualifier - cppreference.com</a></li>
  <li><a href="https://en.wikipedia.org/wiki/Volatile_(computer_programming)">volatile (computer programming) - Wikipedia</a></li>
  <li><a href="https://web.archive.org/web/20110307082444/http://software.intel.com:80/en-us/blogs/2007/11/30/volatile-almost-useless-for-multi-threaded-programming/">Volatile: Almost Useless for Multi-Threaded Programming</a></li>
</ul>

<h2 id="restrict-type-qualifier"><code>restrict</code> type qualifier</h2>

<p>By adding this type qualifier, a programmer hints to the compiler that for
the lifetime of the pointer, no other pointer will be used to access the object
to which it points. This allows the compiler to make optimizations (for example,
vectorization) that would not otherwise have been possible.</p>

<p><span></span></p>

<ul>
  <li><a href="https://en.wikipedia.org/wiki/Restrict">restrict - Wikipedia</a></li>
  <li><a href="https://en.cppreference.com/w/c/language/restrict">restrict type qualifier - cppreference.com</a></li>
  <li><a href="https://www.ibm.com/docs/en/zos/2.5.0?topic=qualifiers-restrict-type-qualifier">The restrict type qualifier - IBM Documentation</a></li>
</ul>

<h2 id="register-type-qualifier"><code>register</code> type qualifier</h2>

<p>It suggests that the compiler stores a declared variable in a CPU register
(or some other faster location) instead of in random-access memory.
The location of a variable declared with this qualifier cannot be accessed
(but the <code>sizeof</code> operator can be applied).</p>

<p>Nowadays <code>register</code> is usually meaningless as modern compilers place variables
in a register if appropriate regardless of whether the hint is given. Sometimes
may it be useful on embedded systems, but even then compiler will probably
provide better optimizations.</p>

<h2 id="flexible-array-member">Flexible array member</h2>

<p>From Wikipedia:</p>

<pre><code class="language-c">struct vectord {
    short len;    // there must be at least one other data member
    double arr[]; // the flexible array member must be last

    // The compiler may reserve extra padding space here,
    //   like it can between struct members.
};

struct vectord *vector = malloc(...);
vector-&gt;len = ...;
for (int i = 0; i &lt; vector-&gt;len; ++i) {
     vector-&gt;arr[i] = ...;  // transparently uses the right type (double)
}
</code></pre>

<ul>
  <li><a href="https://gustedt.wordpress.com/2011/03/14/flexible-array-member/">flexible array member – Jens Gustedt's Blog</a></li>
  <li><a href="https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html">Zero Length (Using the GNU Compiler Collection (GCC))</a></li>
  <li><a href="https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members">The benefits and limitations of flexible array members | Red Hat Developer</a></li>
</ul>

<h2 id="n-format-specifier"><code>%n</code> format specifier</h2>

<p><a href="https://stackoverflow.com/a/8930383/10247460">This StackOverflow answer</a> presents it reasonably well:</p>

<blockquote>
  <p><code>%n</code> returns the current position of the imaginary cursor used when <code>printf()</code> formats its output.</p>

  <pre><code class="language-c">int pos1, pos2;
const char *str_of_unknown_len = "we don't care about the length of this";

printf("Write text of unknown %n(%s)%n length\n", &amp;pos1, str_of_unknown_len, &amp;pos2);
printf("%*s\\%*s/\n", pos1, " ", pos2-pos1-2, " ");
printf("%*s", pos1+1, " ");
for (int i = pos1+1; i &lt; pos2-1; ++i) {
    putc('-', stdout);
}
putc('\n', stdout);
</code></pre>

  <p>will have following output</p>

  <pre><code>Write text of unknown (we don't care about the length of this) length
                      \                                      /
                       --------------------------------------
</code></pre>

  <p>Granted a little bit contrived but can have some uses when making pretty reports.</p>
</blockquote>

<h2 id="-minimum-field-width-format-specifier"><code>%.*</code> (minimum field width) format specifier</h2>

<p>Instead of this:</p>
<pre><code class="language-c">char fmt_buf[MAX_BUF];
snprintf(fmt_buf, MAX_BUF, "%%.%df", prec);
printf(fmt_buf, num);
</code></pre>
<p>do this:</p>
<pre><code>printf("%.*f", prec, num);
</code></pre>
<p>when you want to pad with variable number of characters.</p>

<h2 id="other-less-known-format-specifiers">Other less known format specifiers</h2>

<p>Have a look at <a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf#%5B%7B%22num%22%3A703%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C0%2C792%2C0%5D">§7.21.6.1</a>
and <a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf#%5B%7B%22num%22%3A719%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C0%2C792%2C0%5D">§7.21.6.2</a>
of the draft of C11 standard. You'll find <code>%#</code>, <code>%e</code>, <code>%-</code>, <code>%+</code>, <code>%j</code>, <code>%g</code>, <code>%a</code> and few other interesting specifiers.</p>

<aside>
  <p>I'll update the links to C23 when it's finally done. For now: <code>%b</code> is gonna be standardised!</p>
</aside>

<h2 id="interlacing-syntactic-constructs">Interlacing syntactic constructs</h2>

<p>The following is syntactically correct C code:</p>
<pre><code class="language-c">#include &lt;stdio.h&gt;

int main()
{
    int n = 3;
    int i = 0;

    switch (n % 2) {
        case 0:
            do {
                ++i;
        case 1:
                ++i;
            } while (--n &gt; 0);

    }

    printf("%d\n", i); // 5
}
</code></pre>

<p>I know <code>goto</code>phobic programmers using it like this:</p>
<pre><code class="language-c">    switch (x) {
        case 1:
            // 1 specific code

      if (0) {
        case 2:
            // 2 specific code
      }

            // common for 1 and 2
    }
</code></pre>

<p>The most famous usage of this quirk/"feature" is <a href="https://en.wikipedia.org/wiki/Duff%27s_device">Duff's device</a>:</p>
<pre><code class="language-c">send(to, from, count)
    register short *to, *from;
    register count;
{
    register n = (count + 7) / 8;
    switch (count % 8) {
    case 0: do { *to = *from++;
    case 7:      *to = *from++;
    case 6:      *to = *from++;
    case 5:      *to = *from++;
    case 4:      *to = *from++;
    case 3:      *to = *from++;
    case 2:      *to = *from++;
    case 1:      *to = *from++;
            } while (--n &gt; 0);
    }
}
</code></pre>

<h2 id="---operator"><code>--&gt;</code> "operator"</h2>

<p>The following is correct C code:</p>

<pre><code class="language-c">size_t n = 10;
while (n --&gt; 0) {
    printf("%d\n", n);
}
</code></pre>

<p>You may ask, since when C has such operator and the answer is: since never.
<code>--&gt;</code> is not an operator, but two separate operators <code>--</code> and <code>&gt;</code> written
in a way they look like one. It's possible, because C cares less than more
about whitespace.</p>

<p><code>n --&gt; 0</code> is equivalent of <code>(n--) &gt; 0</code></p>

<h2 id="idxarr"><code>idx[arr]</code></h2>

<p>Square brace notation of accessing array elements is a syntactic sugar for pointer arithmetic:</p>

<div style="width:100%; text-align:center">
  <p><code>arr[5]</code> ≡ <code>*(arr + 5)</code> ≡ <code>*(5 + arr)</code> ≡ <code>5[arr]</code></p>
</div>

<p>You absolutely must never use this in actual code... but it's hella fun otherwise!</p>

<pre><code class="language-c">// array[index]
boxes[products[myorder.product].box].weight;

// index[array]
myorder.product[products].box[boxes].weight;
</code></pre>

<h2 id="negative-array-indexes">Negative array indexes</h2>

<p>For quick and dirty debugging purposes I wanted to check if padding at the end
of an array is filled with correct value, but I didn't know where the padding
starts. Thus, I did the following:</p>

<pre><code class="language-c">int *end = arr + (len - 1);
if (end[0] == VAL &amp;&amp; end[-1] == VAL &amp;&amp; end[-5] == VAL) {
    puts("Correct padding");
}
</code></pre>

<h2 id="constant-string-concatenation">Constant string concatenation</h2>

<p>You don't need <code>sprintf()</code> (nor <code>strcat()</code>!) to concatenate strings literals:</p>

<pre><code>#define WORLD "World!"
const char *s = "Hello " WORLD "\n"
                "It's a lovely day, "
                "innit?";
</code></pre>

<h2 id="backslash-line-splicing">Backslash line splicing</h2>

<p>Each instance of a backslash character <code>\</code> immediately followed by a new-line
character is deleted, splicing physical source lines to form logical source lines.</p>

<pre><code class="language-c">#define I_AM_O\
NE_MACRO 123

// I am a comment. \
   I'm stil the same comment. \
   I'm a so-called ONE-LINE comment!


int fun()
{
    if (drive == 2) // drive 2 is C:\
        return 1;  &lt;-- my firend here is still part of a COMMENT!!

    writestuff();
    return 0;
}

int main()
{
    int x = I_AM_ONE_MACRO;  // correctly expands to 123

    int same_\
variable = 1;
    same_variable = 1;

    const char *p = "String with\
                     so many spaces in the MIDDLE!";

    puts(p); // "String with                     so many spaces in the MIDDLE!"

    return 0;
}
</code></pre>

<h2 id="using--and--as-conditionals">Using <code>&amp;&amp;</code> and <code>||</code> as conditionals</h2>

<p>If you write Shell scripts, you know what I mean.</p>

<pre><code class="language-c">#include &lt;ctype.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdbool.h&gt;

int main(void)
{
    1 &amp;&amp; puts("Hello");
    0 &amp;&amp; puts("I won't");
    1 &amp;&amp; puts("World!");
    0 &amp;&amp; puts("be printed");
    1 || puts("I won't be printed either");
    0 || puts("But I will!");

    true &amp;&amp; (9 &gt; 2) &amp;&amp; puts("9 is bigger than 2");

    isdigit('9') &amp;&amp; puts("9 is a digit");
    isdigit('n') &amp;&amp; puts("n is a digit") || puts("n is NOT a digit!");

    isalpha('a') &amp;&amp; !puts("I'll be printed") || puts("But me AS WELL!");

    return 0;
}
</code></pre>

<p>The compiler will probably scream warnings at you
as it's really uncommon to do this in C code.</p>

<h2 id="compile-time-assumption-checking-using-enums"><a href="https://stackoverflow.com/a/1715239/10247460">Compile time assumption checking using <code>enum</code>s</a></h2>

<pre><code class="language-c">#define D 1
#define DD 2

enum CompileTimeCheck
{
    MAKE_SURE_DD_IS_TWICE_D = 1/(2*(D) == (DD)),
    MAKE_SURE_DD_IS_POW2    = 1/((((DD) - 1) &amp; (DD)) == 0)
};
</code></pre>

<p>Can be useful for libraries with compile-time configurable constants.</p>

<h2 id="ad-hoc-struct-declaration-in-the-return-type-of-a-function">Ad hoc <code>struct</code> declaration in the return type of a function</h2>

<p>You can define <code>struct</code>s in very (at first glance) random places:</p>

<pre><code class="language-c">#include &lt;stdio.h&gt;

struct Foo { int a, b, c; } make_foo(void) {
    struct Foo ret = { .c = 3 };
    ret.a = 11 + ret.c;
    ret.b = ret.a * 3;
    return ret;
}

int main()
{
    struct Foo x = make_foo();
    printf("%d\n", x.a + x.b + x.c);
    return 0;
}
</code></pre>

<h2 id="nested-struct-definition-is-not-kept-nested">"Nested" <code>struct</code> definition is not kept nested</h2>

<pre><code class="language-c">#include &lt;stdio.h&gt;

struct Foo {
    int x;
    struct Bar {
        int y;
    };
};

int main()
{
    struct Bar s = { 34 };  // correct
    // struct Foo.Bar s;    // wrong
    printf("%d\n", s.y);
    return 0;
}
</code></pre>

<h2 id="flat-initializer-lists">Flat initializer lists</h2>

<pre><code>int arr[3][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
//            = { {1,2,3}, {4,5,6}, {7,8,9} };


struct Foo {
    const char *name;
    int age;
};

struct Foo records[] = {
    "John",   20,
    "Bertha", 40,
    "Andrew", 30,
};
</code></pre>

<h2 id="implicit-casting-of-void-pointers">Implicit casting of <code>void</code> pointers</h2>

<p>C11 §6.3.2.3 ¶1:</p>

<blockquote>
  <p>A pointer to <code>void</code> may be converted to or from a pointer to any object type.
 A pointer to any object type may be converted to a pointer to void and back again; 
 the result shall compare equal to the original pointer.</p>
</blockquote>

<p>C11 §6.5.16.1 ¶1:</p>

<blockquote style="display:flex">
  <div style="margin-right: 10px;">&mdash;</div>
  <div>
    the left operand has atomic, qualified, or unqualified pointer type, and
    (considering the type the left operand would have after lvalue conversion)
    one operand is a pointer to an object type, and the other is a pointer to
    a qualified or unqualified version of <code>void</code>, and the type pointed
    to by the left has all the qualifiers of the type pointed to by the right;
  </div>
</blockquote>

<p><code>void*</code> was added to C89 because of a need for generic pointer
type which can be implicitly cast back and forth.</p>

<p>In fact, explicitly casting <code>void</code> pointers has the following problems:</p>

<ul>
  <li>it is unnecessary, as <code>void*</code> is automatically and safely promoted to any other pointer type;</li>
  <li>it adds clutter to the code, casts are not very easy to read (especially if the pointer type is long);</li>
  <li>it makes you repeat yourself;</li>
  <li>it can hide an error would return type change from <code>void*</code> to something more concrete.</li>
</ul>

<h2 id="static-array-indices-in-function-parameter-declarations"><a href="https://www.ibm.com/docs/en/i/7.5?topic=pd-static-array-indices-in-function-parameter-declarations-c-only">Static array indices in function parameter declarations</a></h2>

<blockquote>
  <p>Except in certain contexts, an unsubscripted array name (for example, <code>region</code>
instead of <code>region[4]</code>) represents a pointer whose value is the address of the
first element of the array, provided that the array has previously been declared.
An array type in the parameter list of a function is also converted to the
corresponding pointer type. Information about the size of the argument array
is lost when the array is accessed from within the function body.</p>

  <p>To preserve this information, which is useful for optimization, C99 allows you
to declare the index of the argument array using the static keyword. The constant
expression specifies the minimum pointer size that can be used as an assumption
for optimizations. This particular usage of the static keyword is highly prescribed.
The keyword may only appear in the outermost array type derivation and only in
function parameter declarations. If the caller of the function does not abide
by these restrictions, the behavior is undefined.</p>

  <p>The following examples show how the feature can be used.</p>

  <pre><code class="language-c">int n;
void foo(int arr[static 10]);       // arr points to the first of at least 10 ints
void foo(int arr[const 10]);        // arr is a const pointer
void foo(int arr[const]);           // const pointer to int
void foo(int arr[static const n]);  // arr points to at least n ints (VLA)
</code></pre>
</blockquote>

<p><code>void foo(int p[static 1]);</code> is effectively a standard
way to declare that <code>p</code> must be non-null pointer.</p>

<h2 id="macro-overloading-by-argument-list-length">Macro Overloading by Argument List Length</h2>

<ul>
  <li><a href="https://github.com/Jorenar/CMObALL">CMObALL</a></li>
  <li><a href="https://www.boost.org/doc/libs/master/libs/preprocessor/doc/ref/overload.html">BOOST_PP_OVERLOAD</a></li>
  <li><a href="https://stackoverflow.com/q/16683146/10247460">Can macros be overloaded by number of arguments? - Stack Overflow</a></li>
</ul>

<pre><code class="language-c">#include &lt;stdio.h&gt;
#include "cmoball.h"

#define NoA(...) CMOBALL(FOO, __VA_ARGS__)
#define FOO_3(x,y,z) "Three"
#define FOO_2(x,y)   "Two"
#define FOO_1(x)     "One"
#define FOO_0()      "Zero"


int main()
{
    puts(NoA());
    puts(NoA(1));
    puts(NoA(1,1));
    puts(NoA(1,1,1));
    return 0;
}
</code></pre>

<h2 id="typedef-syntax-is-like-other-specifiers"><code>typedef</code> syntax is like other specifiers</h2>

<p>Usually we declare new types using the following syntax:</p>
<pre><code class="language-c">typedef unsigned char byte;

typedef struct {
    int x;
    int y;
    const char *p;
} Record;
</code></pre>

<p>But other placements of <code>typedef</code> keyword are possible:</p>
<pre><code class="language-c">unsigned typedef char byte;

struct {
    int x;
    int y;
    const char *p;
} typedef Record;
</code></pre>

<p>And we can still declare multiple types in one go:</p>
<pre><code class="language-c">struct {
    int x;
    int y;
    const char *p;
} typedef Record, record, *record_ptr;
</code></pre>

<h2 id="function-types">Function types</h2>

<p>Function pointers ought to be well known, but as we know the syntax is
a bit awkward. On the other hand, less people know you can (as with most
objects in C) create a <code>typedef</code> for function type.</p>

<pre><code class="language-c">#include &lt;stdio.h&gt;

int main()
{
    typedef double fun_t(double);
    fun_t sin, cos, sqrt;
    fun_t *ftpt = &amp;sqrt;

    printf("%lf\n", ftpt(4)); // 2.000000

    return 0;
}
</code></pre>

<h2 id="the-oddities-of-relationship-between-function-designators-and-pointers">The oddities of relationship between function designators and pointers</h2>

<p>Example by u/AnonymouX47 from Reddit post <a href="https://www.reddit.com/r/C_Programming/comments/pxgyee/what_your_weirdest_c_feature/">What your weirdest C feature?</a>:</p>

<blockquote>
  <p>Let's have a simple function prototype: <code>void f(void);</code></p>

  <p>Those lines are equivalent to each other:</p>
  <pre><code class="language-c">void (*fp)(void) = f;
void (*fp)(void) = *f;
void (*fp)(void) = &amp;f;
void (*fp)(void) = ******f;
void (*fp)(void) = &amp;***********f;
void (*fp)(void) = ***&amp;***f;
void (*fp)(void) = &amp;**&amp;***&amp;***&amp;f;
</code></pre>

  <p>Those too are equivalent to each other:</p>
  <pre><code class="language-c">f();
(*f)();
(&amp;f)();
(*&amp;f)();
fp();
(*fp)();
(*&amp;fp)();
(****fp)();
(&amp;******fp)();
(**&amp;**fp)();
(*&amp;*&amp;*&amp;*fp)();
</code></pre>

  <p>But <code>(&amp;fp)()</code> or <code>(&amp;*&amp;*&amp;fp)()</code> won't work.</p>
</blockquote>

<h2 id="x-macros">X-Macros</h2>

<ul>
  <li><a href="https://en.wikipedia.org/wiki/X_Macro">X Macro - Wikipedia</a>
    <ul>
      <li><a href="https://en.wikibooks.org/wiki/C_Programming/Preprocessor#X-Macros">Wikibooks on X macros</a></li>
      <li><a href="https://en.wikibooks.org/wiki/C_Programming/Serialization#X-Macros">C Programming/Serialization/X-Macros</a></li>
    </ul>
  </li>
  <li><a href="https://stackoverflow.com/q/6635851/10247460">Real-world use of X-Macros - Stack Overflow</a></li>
  <li><a href="https://quuxplusone.github.io/blog/2021/02/01/x-macros/">What are X-macros? -- Arthur O'Dwyer</a></li>
  <li><a href="https://bbs.archlinux.org/viewtopic.php?id=272242">X macro: most epic C trick or worst abuse of preprocessor? / Arch Linux Forums</a></li>
  <li><a href="https://philliptrudeau.com/blog/x-macro">The Most Elegant Macro -- Phillip Trudeau</a></li>
  <li><a href="https://digitalmars.com/articles/b51.html">The X Macro - Digital Mars</a></li>
  <li><a href="https://www.drdobbs.com/the-new-c-x-macros/184401387">The New C: X Macros - Dr Dobb's</a></li>
</ul>

<h2 id="x-files">X-Files</h2>

<p>This technique is quite simple to come up with: just think how to make templates
in C using <code>#include</code>. Despite seeing it from time to time in the wild (maybe
even more frequently than X-Macros), seems that until very recently it didn't
even have a name.</p>

<p><a href="https://itnext.io/tutorial-generics-in-c-b3362b3376a3#e687">Here's an article</a>
(<a href="https://archive.is/aTObh#e687">archive</a>) by Chris Bazley, showcasing
a bit of this technique.</p>

<h2 id="named-function-parameters">Named function parameters</h2>

<pre><code class="language-c">struct _foo_args {
    int num;
    const char *text;
};

#define foo(...) _foo((struct _foo_args){ __VA_ARGS__ })
int _foo(struct _foo_args args)
{
    puts(args.text);
    return args.num * 2;
}

int main(void)
{
    int result = foo(.text = "Hello!", .num = 8);
    return 0;
}
</code></pre>

<h2 id="combining-default-named-and-positional-arguments"><a href="https://www.reddit.com/r/C_Programming/comments/yjbe62">Combining default, named and positional arguments</a></h2>

<blockquote>
  <p>Using compound literals and macros to create named arguments (...):</p>

  <pre><code class="language-c">typedef struct { int a,b,c,d; } FooParam;
#define foo(...) foo((FooParam){ __VA_ARGS__ })
void (foo)(FooParam p);
</code></pre>

  <p>adding default arguments is also quite easy:</p>

  <pre><code class="language-c">#define foo(...) foo((FooParam){ .a=1, .b=2, .c=3, .d=4, __VA_ARGS__})
</code></pre>

  <p>But now positional arguments don't work anymore, and there may be situations
where you want to support both options. But I recently realized, that you can
make them work by adding a dummy parameter:</p>

  <pre><code class="language-c">typedef struct { int _; int a,b,c,d; } FooParam;
#define foo(...) foo((FooParam){ .a=1, .b=2, .c=3, .d=4, ._=0, __VA_ARGS__})
</code></pre>

  <p>Now, foo can be called in the following ways:</p>

  <pre><code class="language-c">foo();           // a=1, b=2, c=3, d=4
foo(.a=4, .b=5); // a=4, b=5, c=3, d=5
foo(4, 5);       // a=4, b=5, c=3, d=5
foo(4, 5, .d=8); // a=4, b=5, c=3, d=8
</code></pre>

  <p>The dummy parameter isn't needed when you have arguments that are required to be passed by name:</p>

  <pre><code class="language-c">typedef struct { int alwaysNamed; int a,b,c,d; } FooParam;
#define foo(...) foo((FooParam){.a=1,.b=2,.c=3,.d=4, .alwaysNamed=5, __VA_ARGS__})
</code></pre>
</blockquote>

<aside>
  <p>I've received an e-mail from <a href="https://github.com/miguelrcborges/">Miguel Borges</a>
mentioning that by using GNU extensions, we could make the dummy parameter
costless with empty <code>struct</code>:</p>

  <details>
    <summary>Click to view sent example</summary>

    <pre><code class="language-c">#include &lt;stdio.h&gt;

typedef struct {
} empty;

typedef struct {
	empty _;
	int a;
	int b;
	int c;
} Test;

void _printTest(Test t) {
	printf("a: %d\nb: %d\nc: %d\n\n", t.a, t.b, t.c);
}
#define printTest(...) _printTest((Test){.a = 1, .b = 2, .c = 3, ._ = (empty){}, __VA_ARGS__})

int main(void) {
	printf("size of empty: %zu\n", sizeof(empty));
	printf("size of Test: %zu\n", sizeof(Test));
	printf("\n");

	printf("Default values\n");
	printTest();

	printf("Positional\n");
	printTest(5, 4);

	printf("Named\n");
	printTest(.c = 10, .a = 4);

	printf("Mixed\n");
	printTest(202, .c = 20);

	return sizeof(empty);
}
</code></pre>

  </details>
</aside>

<h2 id="abusing-unions-for-grouping-things-into-namespaces"><a href="https://utcc.utoronto.ca/~cks/space/blog/programming/CUnionsForNamespaces">Abusing unions for grouping things into namespaces</a></h2>

<blockquote>
  <p>Suppose that you have a <code>struct</code> with a bunch of fields, and you want to deal
with some of them all together at once under a single name; perhaps you want
to conveniently copy them as a block through <code>struct</code> assignment.</p>

  <p>By using unions you can access both <code>a.field2</code> and <code>a.sub</code> (and <code>a.field2</code>
is the same as <code>a.sub.field2</code>) without any macros.</p>

  <pre><code class="language-c">struct a {
    int field1;
    union {
        struct {
            int field2;
            int field3;
        };
        struct {
            int field2;
            int field3;
        } sub;
    };
};
</code></pre>
</blockquote>

<h2 id="unity-builds">Unity builds</h2>

<p>Because <code>#include</code> mechanism is essentially a primitive copy-pasting
contents of included file into the current code, C allows us to make
so called <a href="https://en.wikipedia.org/wiki/Unity_build">unity builds</a>,
where we dump everything into one translation unit.</p>

<p>Applying <a href="https://onqtam.com/programming/2018-07-07-unity-builds/">this technique</a>
sometimes may lead to faster compile times, simplified build process or provide
opportunity for optimizations. Unfortunately, is doesn't scale well at all as
it doesn't mix with parallel and incremental builds.
It also hinders modularization/encapsulation of code.</p>

<aside>
  <p>Generating <code>compile_commands.json</code> for LLVM based tools will also be hampered.</p>
</aside>

<h2 id="matching-character-classes-with-sscanf">Matching character classes with <code>sscanf()</code></h2>

<p>From <a href="https://www.reddit.com/r/programming/comments/116iij3/few_lesser_known_tricks_quirks_and_features_of_c/j98zxu5/">this comment</a> on Reddit:</p>

<blockquote>
  <p><code>sscanf()</code> can be used as an ersatz "regex" (not really, only character classes) matcher.
For example, one can write something like this to check if the input consists of letters or underscores:</p>

  <pre><code class="language-c">int len = 0;
char buf[256];
int read_token = sscanf(input, "%255[a-zA-Z_]", buf, &amp;len);
if (read_token) { /* do something */ }
</code></pre>

  <p>or skip whitespace characters:</p>

  <pre><code class="language-c">int len = 0;
char buf[256];
sscanf(input, "%255[\r\n]%n", buf, &amp;len);
input += len;
</code></pre>
</blockquote>

<h2 id="garbage-collector">Garbage collector</h2>

<p><a href="https://www.hboehm.info/gc/">Boehm GC</a> is a library providing garbage collector for C and C++</p>

<h2 id="cosmopolitan-libc"><a href="https://justine.lol/cosmopolitan/index.html">Cosmopolitan Libc</a></h2>

<p>Description from project's website:</p>

<blockquote>
  <p>Cosmopolitan Libc makes C a build-once run-anywhere language, like Java,
except it doesn't need an interpreter or virtual machine. Instead, it
reconfigures stock GCC and Clang to output a POSIX-approved polyglot format
that runs natively on Linux + Mac + Windows + FreeBSD + OpenBSD + NetBSD + BIOS
with the best possible performance and the tiniest footprint imaginable.</p>
</blockquote>

<h2 id="inline-assembly">Inline assembly</h2>

<p>For a high-level language C communicates quite well with low-level world. You
can write Assembly code and link it against program written in C quite easily.
In addition to that, many compilers offer as an extension (listed as common
in Annex J of the C Standard) a feature called <em>inline assembly</em>, typically
introduced to the code by the <code>asm</code> keyword.</p>

<ul>
  <li><a href="https://wiki.osdev.org/Inline_assembly">Inline Assembly - OSDev Wiki</a></li>
  <li><a href="https://en.cppreference.com/w/c/language/asm">Inline assembly - cppreference.com</a></li>
  <li><a href="https://learn.microsoft.com/en-us/cpp/c-language/inline-assembler-c">Inline Assembler (C) | Microsoft Learn</a></li>
  <li><a href="https://developer.arm.com/documentation/100748/0619/Using-Assembly-and-Intrinsics-in-C-or-C---Code/Writing-inline-assembly-code">Writing inline assembly code - Arm Compiler for Embedded User Guide</a></li>
  <li><a href="https://www.cs.uaf.edu/courses/cs301/2014-fall/notes/inline-assembly/">Inline Assembly in C/C++ - University of Alaska Fairbanks</a></li>
</ul>

<h2 id="coroutines">Coroutines</h2>

<p>Apparently there are methods for implementing coroutines in C:</p>

<ul>
  <li><a href="https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html">Coroutines in C</a></li>
  <li><a href="https://en.wikipedia.org/wiki/Coroutine#C">Coroutine#C - Wikipedia</a></li>
  <li><a href="https://www.quora.com/Does-C-support-coroutines">Does C support coroutines? - Quora</a></li>
  <li><a href="https://zelang-dev.github.io/c-coroutine/">c-coroutine</a></li>
  <li><a href="https://libaco.org">Libaco</a></li>
  <li><a href="https://swtch.com/libtask/">Libtask</a></li>
  <li><a href="https://github.com/tidwall/neco">Neco</a></li>
  <li><a href="https://blog.robertelder.org/switch-statements-statement-expressions/">How to Get Fired Using Switch Statements &amp; Statement Expressions</a></li>
</ul>

<h2 id="evaluate-sizeof-at-compile-time-by-causing-duplicate-case-error">Evaluate <code>sizeof</code> at compile time by causing duplicate case error</h2>

<p>Assume you are working on embedded system or generally on something
where getting a <code>printf()</code> output may not be trivial task.</p>

<pre><code>int foo(int c)
{
    switch (c) {
        case sizeof (struct Foo): return c + 1;
        case sizeof (struct Foo): return c + 2;
    }
}
</code></pre>

<p>Adding such simple function anywhere in your code may (depending on compiler)
produce an error message telling us the result of <code>sizeof</code> operator.</p>
<pre><code>error: duplicate case value '16'
        case sizeof(struct Foo): return c + 2;
             ^
</code></pre>

<h2 id="detecting-constant-expressions">Detecting constant expressions</h2>

<pre><code>#define ICE_P(x) _Generic((1 ? ((void*)((x)*(uintptr_t)0)) : &amp;(int){1}), int*: 1, void*: 0)
</code></pre>

<p>Source: <a href="https://www.reddit.com/r/C_Programming/comments/o3ekqe/i_think_i_found_a_c11_compliant_way_to_detect/">I think I found a C11 compliant way to detect constant expressions : r/C_Programming</a></p>

<blockquote>
  <p>TL;DR: Calling <code>ICE_P</code> will evaluate to true if the argument is a constant
expression and otherwise evaluate to false, so the following:</p>
  <pre><code>int x = 3;
printf("%d %d\n", ICE_P(x), ICE_P(3));
</code></pre>
  <p>should print <code>0 1</code>.</p>
</blockquote>

<h2 id="object-oriented-programming">Object Oriented Programming</h2>

<ul>
  <li><a href="https://www.state-machine.com/oop">Object-Oriented Programming in C - Quantum Leaps</a></li>
  <li><a href="https://stackoverflow.com/q/415452/10247460">Object-orientation in C - Stack Overflow</a></li>
  <li><a href="https://www.cs.rit.edu/%7Eats/books/ooc.pdf">Object-Oriented Programming With ANSI C</a></li>
  <li><a href="https://www.cs.tufts.edu/comp/40/docs/CTrapsAndPitfalls.pdf">C Traps and Pitfalls</a> by Andrew Koenig</li>
  <li><a href="https://www.reddit.com/r/C_Programming/comments/mqk338/interesting_ways_to_use_c/guhenr5/">"you can have something like interfaces and virtual methods by using function pointers"</a></li>
</ul>

<h2 id="safeish-variadic-functions">Safe(ish) variadic functions</h2>

<p><a href="https://codeberg.org/NRK/slashtmp/src/branch/master/misc/safe_va_func.c">A trick</a>
by <a href="https://nrk.neocities.org/">NRK</a>:</p>

<blockquote>
  <p>Variadic functions are often sources of subtle bugs because theirs arguments
are not type-checked and can have unintuitive promotion/conversion rules.</p>

  <p>There's also a problem that variadic function doesn't know how many arguments
have been passed to it, thus the caller needs to do it manually, either via
some sentinel value that marks the end of arguments (e.g <code>execl()</code> using
<code>NULL</code> to mark the end) or by passing the size via another parameter.</p>

  <p>With some clever usage of C99's variadic macros, combined with compound
literals, these shortcomings can be worked around.<br />
While the below example only works when all parameters are of the same type,
in cases where different types might be needed, it <em>should</em> be possible to
extend this trick with "tagged union" and some usage of C11's <code>_Generic</code>.</p>
</blockquote>

<pre><code class="language-c">#include &lt;stdio.h&gt;

void print_vec(FILE *f, const int *v, size_t n)
{
    for (size_t i = 0; i &lt; n; ++i) {
        fprintf(f, "%d\n", p[i]);
    }
}
#define print_vec(fstream, ...)                                     \
    print_vec((fstream),                                            \
              (const int[]){ __VA_ARGS__ },                         \
              (sizeof (int[]){ __VA_ARGS__ } / sizeof (int)) )

int main(void)
{
    print_vec(stdout, 1);
    print_vec(stdout, 1, 2, 3);
    print_vec(stdout, 1, 2, 3, 4, 5);
    return 0;
}
</code></pre>

<h2 id="metaprogramming">Metaprogramming</h2>

<p>C11 added <code>_Generic</code> to language, but turns out metaprogramming
by inhumanely abusing the preprocessor is possible even in pure C99:
meet <a href="https://metalang99.readthedocs.io"><strong>Metalang99</strong></a> library.</p>

<pre><code>#include &lt;datatype99.h&gt;

datatype(
    BinaryTree,
    (Leaf, int),
    (Node, BinaryTree *, int, BinaryTree *)
);

int sum(const BinaryTree *tree) {
    match(*tree) {
        of(Leaf, x) return *x;
        of(Node, lhs, x, rhs) return sum(*lhs) + *x + sum(*rhs);
    }

    return -1;
}
</code></pre>

<h2 id="preprocessor-is-a-language-of-its-own">Preprocessor is a language of its own</h2>

<p>I've already mentioned some preprocessor tricks, but there's way more!
In fact, I could easily make such a list out of preprocessor oddities alone.
After all, it is a full fledged language with its own rules, grammar, and
caveats; heck, it's not even strictly exclusive to C - there are madlads
<a href="https://www.nongnu.org/espresso/js-cpp.html">using it in conjunction with e.g. JavaScript</a>.</p>

<p>Luckily for me, <a href="https://hirrolot.github.io/"><em>hirrolot</em></a> - the author
of aforementioned Metalang99, has already prepared
<a href="https://github.com/hirrolot/awesome-c-preprocessor">awesome-c-preprocessor</a>
list with sane and insane deeds possible to do in C preprocessor.</p>

<h2 id="ccan">CCAN</h2>

<p><a href="https://ccodearchive.net/">Comprehensive C Archive Network</a>, modeled
after Perl's <a href="https://www.cpan.org/">CPAN</a> (which in turn was modeled
after <a href="https://en.wikipedia.org/wiki/CTAN">CTAN</a>) is a repository of
C code snippets. While it's not such a necessity like for Perl, nor
is it officially endorsed or widely used, I think its existence is
interesting enough to warrant a mention.</p>

<h2 id="function-pointers-to-match-arrays-in-_generic">Function pointers to match arrays in <code>_Generic</code></h2>

<p>Right now <code>_Generic</code> doesn't allow for matching arrays, but document
<a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3348.pdf">N3348</a>
by Martin Uecker mentions <a href="https://godbolt.org/z/bqhrEcGn4">a trick</a>
to make them match by wrapping the type into a function pointer:</p>

<pre><code class="language-c">#include &lt;stdio.h&gt;

#define LENGTHOF(arr) (sizeof (arr) / sizeof (arr)[0])

#define FOO(n,m) \
        _Generic(void (*)(int(*)[n][m]), \
                 void (*)(int(*)[3][6]) : 1, \
                 void (*)(int(*)[3][3]) : 2, \
                 void (*)(int(*)[2][8]) : 3, \
                 void (*)(int(*)[4][*]) : 4, \
                 void (*)(int(*)[8][*]) : 5 \
        )

#define BAR(arr) FOO(LENGTHOF(arr), LENGTHOF(arr[0]))

int main()
{
    printf("%d\n", FOO(3,6)); // 1
    printf("%d\n", FOO(3,3)); // 2
    printf("%d\n", FOO(2,8)); // 3
    printf("%d\n", FOO(4,0)); // 4
    printf("%d\n", FOO(4,1)); // 4
    printf("%d\n", FOO(4,2)); // 4

    int arr[8][2];
    printf("%d\n", BAR(arr)); // 5

    // printf("%d\n", FOO(5,2)); // error

    return 0;
}
</code></pre>

<h2 id="polyglot-files"><a href="https://en.wikipedia.org/wiki/Polyglot_(computing)#C,_PHP,_and_Bash">Polyglot files</a></h2>

<p>A polyglot file is composed by combining syntax from different languages.
The linked Wikipedia article showcases such combination of C, PHP, and Bash.</p>

<p>A more realistic example for C would be for embedding compilation command:</p>

<pre><code class="language-c">#if 0
cc -o hello $0 &amp;&amp; exec ./hello
exit # in case of compilation failure
#endif

#include &lt;stdio.h&gt;

int main(void)
{
    puts("Hello World!");
    return 0;
}
</code></pre>

<p>And because POSIX specifies that text files without shebang shall
be executes as shell script, in compliant environment you can have:</p>

<pre><code class="language-sh">$ ./hello.c
Hello World!
$
</code></pre>

<p><a href="https://github.com/skeeto/w64devkit/blob/master/src/libmemory.c">Here you can see a real life example of this technique usage</a>.</p>

<h2 id="forward-declaration-is-optional">Forward declaration is optional</h2>

<p>Normally forward declaration is done as following:</p>
<pre><code class="language-c">struct Foo;
void bar(int n, struct Foo *a)
{
    if (n) bar(n-1, a);
}
</code></pre>

<p>but we can declare and initialize a pointer in one go too:</p>
<pre><code class="language-c">struct Foo *g = 0;
void bar(int n, struct Foo *a)
{
    if (n) bar(n-1, a);
}
</code></pre>

<p>or skip global forward declaration:</p>
<pre><code class="language-c">void bar(int n, struct Foo *a)
{
    if (n) bar(n-1, a);
}
</code></pre>

<p>Although, beware: technically in</p>
<pre><code>void bar(int n, struct Foo *a);
void baz(struct Foo *b);
</code></pre>
<p>pointers <code>a</code> and <code>b</code> are incompatible.</p>

<aside>
  <ul>
    <li><a href="https://stackoverflow.com/questions/16831605">Strange compiler warning C: warning: 'struct' declared inside parameter list - Stack Overflow</a></li>
  </ul>
</aside>]]></content><author><name>Jorenar</name></author><summary type="html"><![CDATA[There are some tricks, quirks, and features which seems to throw even experienced developers off the track. Thus, I periodically revisit this blogpost, to do a sloppy job of gathering them in an unordered list with some short explanations, examples, quotes, or references.]]></summary></entry><entry><title type="html">Legitimate use-cases of VM types in C</title><link href="https://jorenar.com/vla-usecases" rel="alternate" type="text/html" title="Legitimate use-cases of VM types in C" /><published>2023-02-10T00:00:00+00:00</published><updated>2023-02-10T00:00:00+00:00</updated><id>https://jorenar.com/vla-usecases</id><content type="html" xml:base="https://jorenar.com/vla-usecases"><![CDATA[<p>An earlier version of my <a href="/blog/vla-pitfalls">Pitfalls of VLA in C</a> article
contained an example of useful case of VLA, but since there are actually
two of them (and I'd be overjoyed being presented with more), they deserve
a dedicated, if low effort, post of their own. After all, those use-cases
are the only reason why I compile with <code>-Wvla-larger-than=0</code> rather than
more strict and reliable <code>-Wvla</code>.</p>

<h1 id="size-check-when-passing-to-function">Size check when passing to function</h1>

<p>"Only" a bit over two decades after the introduction of VLA to C language,
GCC started giving warnings about passing to functions bigger than declared
size of arrays when we actually decide to utilize VLA syntax in parameters.</p>

<pre><code class="language-c">#include &lt;stdio.h&gt;

void f(const size_t size, const int buf[static size]);

int main(void)
{
    int arr[50] = { 0 };
    f(10, arr);  // acceptable
    f(50, arr);  // correct
    f(100, arr); // *WARNING*
    return 0;
}
</code></pre>

<p><strong>Added bonus:</strong> explicit size annotation</p>

<h1 id="multidimensional-arrays">Multidimensional arrays</h1>

<p>Dynamically allocating multi-dimensional arrays where the inner dimensions
are not known until runtime is really simplified using VM types.
It isn't even as unsafe as aVLA since there's no arbitrary stack allocation.</p>

<pre><code class="language-c">int (*arr)[n][m] = malloc(sizeof *arr); // `n` and `m` are variables with dimensions
if (arr) {
    // (*arr)[i][j] = ...;
    free(arr);
}
</code></pre>

<p>The VLA-free alternatives aren't as sexy:</p>

<ul>
  <li><strong>piecemeal allocation</strong>
    <pre><code class="language-c">int **arr = malloc(n * (sizeof *arr));
if (arr) {
    for (int i = 0; i &lt; n; ++i) {
        arr[i] = malloc(m * (sizeof *arr[i]));
    }
    // arr[i][j] = ...
    for (int i = 0; i &lt; n; ++i) {
        free(arr[i]);
    }
    free(arr);
}
</code></pre>
  </li>
  <li><strong>1D array with offsets</strong>
    <pre><code class="language-c">int *arr = malloc(n * m * (sizeof *arr));
if (arr) {
    // arr[i*n + j] = ...
    free(arr);
}
</code></pre>
  </li>
  <li><strong>big fixed array</strong>
    <pre><code class="language-c">int arr[SAFE_SIZE][SAFE_SIZE]; // SAFE_SIZE must be safe for SAFE_SIZE*SAFE_SIZE
// arr[i][j] = ...;
</code></pre>
  </li>
</ul>

<!-- Some bug(?) eats 4 first spaces of indent, thus 8 spaces used -->]]></content><author><name>Jorenar</name></author><summary type="html"><![CDATA[An earlier version of my Pitfalls of VLA in C article contained an example of useful case of VLA, but since there are actually two of them (and I'd be overjoyed being presented with more), they deserve a dedicated, if low effort, post of their own. After all, those use-cases are the only reason why I compile with -Wvla-larger-than=0 rather than more strict and reliable -Wvla.]]></summary></entry><entry><title type="html">Pitfalls of VLA in C</title><link href="https://jorenar.com/vla-pitfalls" rel="alternate" type="text/html" title="Pitfalls of VLA in C" /><published>2021-07-05T00:00:00+00:00</published><updated>2021-07-05T00:00:00+00:00</updated><id>https://jorenar.com/vla-pitfalls</id><content type="html" xml:base="https://jorenar.com/vla-pitfalls"><![CDATA[<blockquote>
  <p>It generates much more code, and much <em>slower</em> code (and more fragile code),
  than just using a fixed key size would have done ~ <a href="https://lkml.org/lkml/2018/3/7/621">Linus Torvalds</a></p>
</blockquote>

<p>VLA (<strong>variable-length array</strong>, an array -- <em>array</em>, not just block of memory
acting like one -- that has size determined during runtime instead of at compile
time) is a feature introduced to C with the revision C99 of the standard.
A very useful feature one may think, and indeed... in some cases...
But since the world we live in is less than ideal, one needs to know well what
are the pitfalls of using VLA in their code before doing so.</p>

<p>If you want to know the few cases when VLA may actually
be useful you can check <a href="/blog/vla-usecases">my other blogpost</a>.</p>

<p>A fair share of the text here will focus on problems caused by automatic VLA,
thus to further reflect on that an abbreviation <em>aVLA</em> will be used when
referring to those cases.</p>

<h1 id="allocation-on-stack">Allocation on stack</h1>

<p>Let's address the elephant in the room: the standard doesn't say anything about
it, but in practice aVLA usually are allocated on stack. This is the source of
the most of the problems, the source of discontent among programmers, the reason
why even allowing any VLA into the codebase is usually a code smell.</p>

<p>Let's consider a painfully simple, very favourable to aVLA, example:</p>
<pre><code class="language-c">#include &lt;stdio.h&gt;

int main(void) {
    int n;
    scanf("%d", &amp;n);
    char arr[n];
    printf("%d", arr[0]);
    return 0;
}
</code></pre>

<p>As we can see, it takes a number from user then makes array of that size. Compile
and try it. Check how big values you can input before getting segfault caused
by stack overflow. <a href="https://godbolt.org/z/45arWxWo7">In my case, it was around 8 MiB</a>.
How much is that? One raw image? a MP3 or two? few seconds of video? And the program
wasn't doing anything meaningful - what if it wasn't just <code>main()</code>? Maybe a recursive
function? The limit shrinks tremendously.</p>

<p>And you don't have any (portable, standard) way to react after a stack
overflow - the program already <em>crashed, you lost control</em>. So you either need
to make elaborate checks before declaring an array or betting that user won't
input too large values (the outcome of such gamble ought to be obvious).</p>

<p>So the programmer <strong>must</strong> ensure that aVLA size doesn't exceed some safe maximum,
but in reality, if you know safe maximum, there is rarely any reason for not using
it always.</p>

<h2 id="worst-of-it-is">Worst of it is...</h2>

<p>... that segfault is actually one of the best outcomes of improperly handled aVLA.
The worst case is an exploitable vulnerability, where attacker may choose a value
that causes an array to overlap with other allocations, giving them control over
those values as well. A security nightmare.</p>

<aside>
  <p>At the cost of further drop of efficiency, in GCC you can enable
<code>-fstack-clash-protection</code> option. It adds <em>extra</em> instructions around
variable length stack memory allocations to probe each page of memory at
allocation time. This mitigates stack-clash attacks by ensuring all stack
memory allocations are valid or by throwing a segfault if they are not, thus
turning a possible code-execution attack into a denial of service.</p>
</aside>

<h2 id="so-how-to-fix-this-example">So how to fix this example?</h2>

<p>What if I need to let user define size and creating ridiculously large fixed
array would be too wasteful? It's simple: use <code>malloc()</code>!</p>
<pre><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

int main(void) {
    int n;
    scanf("%d", &amp;n);
    char *arr = malloc(n * (sizeof *arr));
    printf("%d", arr[0]);
    free(arr);
    return 0;
}
</code></pre>

<p>In this case I was able to request over 4.5 GiB before segfault. Almost few orders
of magnitude more! But I still got the segfault, right? Well, the difference
is in getting at least some* chance of checking the value returned by <code>malloc()</code>
and thus being able to, for example, inform the user about the error:</p>
<pre><code class="language-c">    char *arr = malloc(n * (sizeof *arr));
    if (arr == NULL) {
        perror("malloc()"); // output: "malloc(): Cannot allocate memory"
    }
</code></pre>
<aside>
  <p>* Only "some" chance because while it usually doesn't cause problems,
operating systems may (and do) use something called <a href="https://en.wikipedia.org/wiki/Memory_overcommitment">memory overcommitment</a>
which rarely, but still, may be a little... <a href="https://www.win.tue.nl/~aeb/linux/lk/lk-9.html#ss9.6">broken sometimes</a>.</p>
</aside>

<h3 id="but-i-cannot-use-malloc">"but I cannot use <code>malloc()</code>!"</h3>

<p>I've encountered a counterargument, that as C is often used as a systems/embedded
language, there are situations where using <code>malloc()</code> may not even be possible.</p>

<p>I'm basically going to repeat myself here, but it is really important:</p>

<ol>
  <li>
    <p>Such device rather is not going to have a lot of stack either. So instead of
allocating dynamically, you (probably) should determine how much you need and
just always use that fixed amount.</p>
  </li>
  <li>
    <p>When using aVLA on system with small amounts of stack, it's really easy to make
something which seems to work, but which blows your stack if your function gets
called from a deep call stack combined with the large amount of data.</p>
  </li>
  <li>
    <p>If you always allocate fixed amounts of stack space everywhere, and you test
it, you know you're good. If you dynamically allocate on stack, you have to
test all your code paths with all the largest sizes of allocated space, which
is much harder and much easier to make a mistake. Don't make it even easier to
shoot yourself in the foot for no real advantage.</p>
  </li>
</ol>

<h1 id="creation-by-accident">Creation by accident</h1>

<p>Unlike most other dangerous C functionality, aVLA doesn't have the barrier
of being not known. Many newbies learn to use them via trial and error, but
don't learn about the pitfalls. <br />
The following is a simple mistake I observed even experienced developers making
(especially those with C++ background); it will silently create an aVLA when
it's clearly not necessary:</p>
<pre><code class="language-c">const int n = 10;
int A[n];
</code></pre>
<p>Thankfully, any half-decent compiler would notice and optimize aVLA away, but...
what if it doesn't notice? Or what if, for some reason (safety?), the optimizations
were not turned on? But it surely isn't so much worse, right? Well...</p>

<h1 id="way-slower-than-fixed-size">Way slower than fixed size</h1>

<p>Without compiler optimizations a function with <a href="https://godbolt.org/z/Pe6sqEqv1">aVLA from previous
example</a> will result in <strong>7 times</strong> more Assembly
instructions than its <a href="https://godbolt.org/z/7h9zevrPq">fixed size counterpart</a>
before moving past the array definition (look at the body before <code>jmp .L2</code>).
But it's without optimizations, with them the produced Assembly is exactly the same.</p>

<p>So <a href="https://godbolt.org/z/4qeYhzTbn">an example where aVLA is not used by mistake</a>:</p>
<pre><code class="language-c">#include &lt;stdio.h&gt;
void bar(int*, int);

void foo(int n) {

#if VLA
    int A[n];
#else
    int A[1000];  // Let's make it bigger than 10!
                  // (or there won't be what to examine)
#endif

    for (int i = n; i--;) {
        scanf("%d", &amp;A[i]);
    }
    bar(A, n);
}

int main(void) {
    foo(10);
    return 0;
}
</code></pre>
<p>For our educational purposes in this example, <code>-O1</code> level of optimisation will
work best (as Assembly will be clearer and <code>-O2</code> won't help aVLA's case here
really much).</p>

<p>When we compile aVLA version, before instructions corresponding to <code>for</code> loop, we get:</p>
<pre><code class="language-nasm">push    rbp
mov     rbp, rsp
push    r14
push    r13
push    r12
push    rbx
mov     r13d, edi
movsx   r12, edi       ; here aVLA "starts"...
sal     r12, 2         ;
lea     rax, [r12+15]  ;
and     rax, -16       ;
sub     rsp, rax       ;
mov     r14, rsp       ; ... and there "ends"
</code></pre>

<p>The aVLA-free version on the other hand generates:</p>
<pre><code class="language-nasm">push    r12
push    rbp
push    rbx
sub     rsp, 4000      ; this is caused by array definition
mov     r12d, edi
</code></pre>

<p>So not only fixed array spawns less code, but also way simpler code.
Why, aVLA even causes more overhead at the beginning of the function.
It's not so much more in the grand scheme of things, but it still isn't
just a pointer bump.</p>

<p>But are those differences significant enough to care?
<a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=02361bc77888">Yes, they are</a>.</p>

<h1 id="no-initialization">No initialization</h1>

<p>To add more to the issue with inadvertent aVLA, the following isn't allowed:</p>
<pre><code class="language-c">int n = 10;
int A[n] = { 0 };
</code></pre>
<p>Even with optimizations, initialisation isn't allowed for aVLA. So despite
wanting fixed size array and compiler being technically able to provide one,
it won't work (and if it does... it's breaking the specification...).</p>

<h1 id="sizeof-not-resolved-at-compile-time"><code>sizeof</code> not resolved at compile time</h1>

<pre><code class="language-c">int n;
scanf("%d", &amp;n);
int A[5];
int B[n];

sizeof A;  // compile-time
sizeof B;  // run-time
</code></pre>

<p>The above is quite obvious, <code>B</code> isn't fully known until <code>n</code> gets its value,
thus it needs to be resolved at run-time. Nothing to write home about.</p>

<p>On the other hand, the following is no longer so obvious
(<a href="https://www.reddit.com/r/C_Programming/comments/11e9ewe/constant_variable_length_arrays/jadfka5/">source of example</a>):</p>

<blockquote>
  <p>The operand [of <code>sizeof</code> operator] must be <em>evaluated</em> if its type is a VLA; for example:</p>

  <pre><code class="language-c">int i = 0;
static const int n = 5;

int A[5];
int B[n];
sizeof A[i++];   // operand is not evaluated, `i` is still 0
sizeof B[i++];   // operand is evaluated, `i` is 1
sizeof &amp;B[i++];  // operand is not evaluated, `i` stays 1
</code></pre>
</blockquote>

<h1 id="mess-for-compiler-writers">Mess for compiler writers</h1>

<p>Few months ago I saved a <a href="https://www.reddit.com/r/C_Programming/comments/jz2213/are_vlas_bad_even_if_theyre_not_allocated_on_the/gdc3hz6">comment</a>
on Reddit listing problems encountered with VLA from compiler writer perspective.
I'll allow myself to cite the listed issues:</p>

<blockquote>
  <ul>
    <li>A VLA applies to a type, not an actual array. So you can create a <code>typedef</code>
of a VLA type, which "freezes" the value of the expression used, even if
elements of that expression change at the time the VLA type is applied</li>
    <li>VLAs can occur inside blocks, and inside loops. This means allocating and
deallocating variable-sized data on the stack, and either screwing up all
the offsets, or needing to do things indirectly via pointers.</li>
    <li>You can use <code>goto</code> into and out of blocks with active VLAs, with some things
restricted and some not, but the compiler needs to keep track of the mess.</li>
    <li>VLAs can be used with multi-dimensional arrays.</li>
    <li>VLAs can be used as pointer targets (so no allocation is done, but it still
needs to keep track of the variable size).</li>
    <li>Some compilers allow VLAs inside structure definitions (I really have no idea
how that works, or at what point the VLA size is frozen, so that all instances
have the same VLA(s) sizes.)</li>
    <li>A function can have dozens of VLAs active at any one time, with some being
created or destroyed at different times, or conditionally, or in loops.</li>
    <li><code>sizeof</code> needs to be specially implemented for VLAs, and all the necessary
info (for actual VLAs, VLA-types, and hybrid VLA/fixed-size types and
arrays and pointed-to VLAs).</li>
    <li>'VLA' is also the term used for multi-dimensional array parameters, where
the dimensions are passed by other parameters.</li>
    <li>On Windows, with some compilers (GCC at least), declaring local arrays which
make the stack frame size over 4 KiB, mean calling a special allocator
(<code>__chkstk()</code>), as the stack can only grow a page at a time. When a VLA is
declared, since the compiler doesn't know the size, it needs to call
<code>__chkstk</code> for every such function, even if the size turns out to be small.</li>
  </ul>
</blockquote>

<p>And believe me, if you take a stroll around some C forums (or the meeting of
standard committee [sic!]) you will see even more different complaints.</p>

<h1 id="reduced-portability">Reduced portability</h1>

<p>Due to all previously presented problems, some compiler providers decided to
not fully support C99. The primary example is Microsoft with its MSVC.
The C Standard Committee also noticed the problem and with C11 revision
all instances of VLAs were made optional; C23 partially reverts that decision
mandating VM types (aVLA are still optional; there is even a slight sentiment
towards deprecating them entirely, but removing something from the, nomen omen,
standard is way harder than putting it in).</p>

<p>That means code using a VLA won't necessarily be compiled by a C11 compiler,
so you need, assuming you target for portability, to check whether it is
supported with <code>__STDC_NO_VLA__</code> macro and make version without (a)VLA as
fallback. Wait... if you need to implement VLA-free version either way then
what's the point of doubling the code and creating VLA in the first place?!</p>

<aside>
  <p>As a side note: C++ doesn't have VLA and nothing suggests
it ever will (other than as implementation extension).<br />
Not a dealbreaker, but still point against VLA in C.</p>
</aside>

<h1 id="nitpick-breaking-conventions">(nitpick) Breaking conventions</h1>

<p>This one is more of a nitpick, but still another reason to dislike VLA. There
is a widely used convention of first passing object then its parameters, what
in terms of arrays means:</p>
<pre><code class="language-c">void foo(int** arr, int n, int m) { /* arr[i][j] = ... */ }
</code></pre>

<p>C99 specified that array sizes need to be parsed immediately when encountered
within a function definition's parameter list, what means that when using VLA
you cannot do an equivalent of the above:</p>
<pre><code class="language-c">void foo(int arr[n][m], int n, int m) { /* arr[i][j] = ... */ } // INVALID!
</code></pre>

<p>You need to break up with the convention and write:</p>
<pre><code class="language-c">void foo(int n, int m, int arr[n][m]) { /* arr[i][j] = ... */ }
</code></pre>

<p>Alternatively, you could use the obsolete syntax (obsolescent even in
ANSI C; finally removed in C23), but that would be pointless, as
compilers don't make parameters checks in such case, so any benefits
from using VLA would be lost.</p>
<pre><code class="language-c">void foo(int[*][*], int, int);
void foo(arr, n, n)
    int n;
    int m;
    int arr[n][m]
{
    // arr[i][j] = ...
}
</code></pre>

<aside>
  <p>There is a chance a GCC extension - <em>forward declaration of parameters</em> - will
be standardized in C2y.</p>
</aside>

<h1 id="conclusion">Conclusion</h1>

<p>In short, refrain from using VLA and <strong>avoid automatic VLA like devil avoids
holy water</strong>; if your compiler has it, rather compile with <code>-Wvla</code> flag
or similar (and definitely with <code>-Wvla-larger-than=0</code> - this allows VM types,
while warning about aVLA).</p>

<p>If you find yourself in one of the situations where VLA (or VM type) is a valid/good
solution, of course, do use them, but keep in mind the limits I've outlined here.</p>

<aside>
  <p>It's probably also worth mentioning that VLAs were partially supposed to be
a solution to non-standard <code>alloca()</code> function, which is even more problematic
when it comes to stack.</p>
</aside>

<aside>
  <p>As you could have guessed by the quote at the beginning, project which used to
rely on VLA quite extensively (209 unique locations reported in 60 directories!)
is nothing else than Linux kernel. Maintainers spent a lot of effort to get rid
of all VLA and as of version 4.20 (year 2018) it's completely VLA-free.</p>
</aside>]]></content><author><name>Jorenar</name></author><summary type="html"><![CDATA[It generates much more code, and much slower code (and more fragile code), than just using a fixed key size would have done ~ Linus Torvalds]]></summary></entry><entry><title type="html">Steps to learn Vim</title><link href="https://jorenar.com/vim-learning-steps" rel="alternate" type="text/html" title="Steps to learn Vim" /><published>2021-01-23T00:00:00+00:00</published><updated>2021-01-23T00:00:00+00:00</updated><id>https://jorenar.com/vim-learning-steps</id><content type="html" xml:base="https://jorenar.com/vim-learning-steps"><![CDATA[<ol start="0">
  <li>Learn <a href="http://www.catb.org/~esr/faqs/smart-questions.html">how to ask questions the smart way</a></li>
  <li><a href="https://vimhelp.org/usr_01.txt.html#vimtutor"><code>vimtutor</code></a> teaches the most basic Vim functionality hands-on</li>
  <li><a href="https://vimhelp.org/usr_toc.txt.html"><code>:h user-manual</code></a> will guide you through every feature from basic to advanced</li>
  <li><a href="https://vimhelp.org/vim_faq.txt.html"><code>:h faq</code></a> - Frequently Asked Questions</li>
  <li><a href="https://vimhelp.org/quickref.txt.html"><code>:h quickref</code></a> - quick reference guide</li>
  <li><a href="https://vimhelp.org/"><code>:help</code></a> and <code>:helpgrep</code> to find more details about a specific feature</li>
  <li><a href="/blogroll#vim">Check other resources I've gathered</a></li>
  <li>USE IT!</li>
</ol>

<hr />

<aside>
  <p>The following is a copy of <a href="https://web.archive.org/web/20250816100058/https://vi-improved.org/vim-proverbs/">Vim Proverbs</a> originally published on 2016-05-31</p>
</aside>

<p>Tidbits of wisdom from <a href="https://web.archive.org/web/20250821134602/https://vi-improved.org/ops/">greybeards</a></p>

<ul>
  <li>It is a text editor, not an IDE</li>
  <li>It probably has that feature built in</li>
  <li>Move with deliberate purpose</li>
  <li>The documentation is better than you imagine</li>
  <li>HJKL is <strong>not</strong> an important part of vim navigation</li>
  <li>Project drawers conflict with split windows, favor splits</li>
  <li>Visual clutter saps mental energy</li>
  <li>Use plugins sparingly</li>
  <li>Navigate by tags and search, not files</li>
  <li>If it feels hard, there is probably a better way</li>
  <li>You should understand every line in your vimrc</li>
  <li>UI "tabs" are probably not what you expect</li>
  <li>Don't seek mastery, seek proficiency</li>
</ul>]]></content><author><name>Jorenar</name></author><summary type="html"><![CDATA[Learn how to ask questions the smart way vimtutor teaches the most basic Vim functionality hands-on :h user-manual will guide you through every feature from basic to advanced :h faq - Frequently Asked Questions :h quickref - quick reference guide :help and :helpgrep to find more details about a specific feature Check other resources I've gathered USE IT!]]></summary></entry><entry><title type="html">Vim with XDG Dirs</title><link href="https://jorenar.com/vim-xdg" rel="alternate" type="text/html" title="Vim with XDG Dirs" /><published>2020-12-13T00:00:00+00:00</published><updated>2020-12-13T00:00:00+00:00</updated><id>https://jorenar.com/vim-xdg</id><content type="html" xml:base="https://jorenar.com/vim-xdg"><![CDATA[<p>XDG Base Directory specification, <code>$XDG_CONFIG_HOME</code> etc. Great thing - configs
separated from user data and cache, no clutter in home directory. Unfortunately,
many programs still don't respect it, including Vim. But what would be our favourite
text editor if we wouldn't be able to reconfigure it!</p>

<h1 id="tldr">TL;DR</h1>

<p>Into environment/shell config (e.g. in <code>~/.profile</code>):</p>
<pre><code class="language-sh">if [ -x "$(command -v vim)" ]; then
    [ "$(vim --clean -es +'exec "!echo" has("patch-9.1.0327")' +q)" -eq 0 ] &amp;&amp; \
        export VIMINIT="set nocp | source ${XDG_CONFIG_HOME:-$HOME/.config}/vim/vimrc"
fi
</code></pre>

<p>At the top of <em>vimrc</em>:</p>
<pre><code class="language-vim">" XDG Base Directory support

if empty($MYVIMRC) | let $MYVIMRC = expand('&lt;sfile&gt;:p') | endif

if empty($XDG_CACHE_HOME)  | let $XDG_CACHE_HOME  = $HOME."/.cache"       | endif
if empty($XDG_CONFIG_HOME) | let $XDG_CONFIG_HOME = $HOME."/.config"      | endif
if empty($XDG_DATA_HOME)   | let $XDG_DATA_HOME   = $HOME."/.local/share" | endif
if empty($XDG_STATE_HOME)  | let $XDG_STATE_HOME  = $HOME."/.local/state" | endif

if !has('nvim')
  set runtimepath^=$XDG_CONFIG_HOME/vim
  set runtimepath+=$XDG_DATA_HOME/vim
  set runtimepath+=$XDG_CONFIG_HOME/vim/after

  set packpath^=$XDG_DATA_HOME/vim,$XDG_CONFIG_HOME/vim
  set packpath+=$XDG_CONFIG_HOME/vim/after,$XDG_DATA_HOME/vim/after

  set backupdir=$XDG_STATE_HOME/vim/backup | call mkdir(&amp;backupdir, 'p', 0700)
  set directory=$XDG_STATE_HOME/vim/swap   | call mkdir(&amp;directory, 'p', 0700)
  set viewdir=$XDG_STATE_HOME/vim/view     | call mkdir(&amp;viewdir,   'p', 0700)
  set undodir=$XDG_STATE_HOME/vim/undo     | call mkdir(&amp;undodir,   'p', 0700)
  set viminfofile=$XDG_STATE_HOME/vim/viminfo
endif

let g:netrw_home = $XDG_DATA_HOME."/vim"
call mkdir($XDG_DATA_HOME."/vim/spell", 'p', 0700)
call mkdir($XDG_STATE_HOME."/vim", 'p', 0700)
</code></pre>

<h1 id="step-by-step">Step-by-step</h1>
<h2 id="relocating-vimrc">Relocating <em>vimrc</em></h2>

<p>Since version 7.3.1178, Vim will search for <code>~/.vim/vimrc</code> if <code>~/.vimrc</code>
is not found. So let's move the file there.</p>

<p>Let's move our <code>~/.vim</code> to <code>$XDG_CONFIG_HOME/vim</code>. Now we need to command Vim
to read config from this new location prior to <code>~/.vim</code>.</p>

<p>If you have Vim 9.1.0327 or newer, you are in luck! From that version Vim
looks for <code>$XDG_CONFIG_HOME/vim/vimrc</code> on its own, no further hacks required.</p>

<p>We can move on to configuring inside our <em>vimrc</em>.</p>

<aside>

  <p>In case you have a Vim version older than 9.1.0327, there are three
workarounds you can choose from:</p>

  <h3>Shell alias</h3>
  <div>
    <p>Pretty straightforward method.<br />
Shell will just substitute command <code>vim</code> with the alias body.</p>

    <pre><code class="language-sh">alias vim='vim -u ${XDG_CONFIG_HOME:-$HOME/.config}/vim/vimrc'
</code></pre>

    <p>Downside? Works only in shell.</p>
  </div>

  <h3><code>VIMINIT</code> environmental variable</h3>
  <div>
    <pre><code class="language-sh">export VIMINIT="set nocp | source ${XDG_CONFIG_HOME:-$HOME/.config}/vim/vimrc"
</code></pre>

    <p>Cons? If you wish for Neovim and Vim configurations to still be separated, then:</p>

    <pre><code class="language-sh">export VIMINIT="
  if has('nvim')
    so ${XDG_CONFIG_HOME:-$HOME/.config}/nvim/init.vim
  else
    set nocp
    so ${XDG_CONFIG_HOME:-$HOME/.config}/vim/vimrc
  endif
"
</code></pre>
  </div>

  <p>and of course, you are taking it away from other purposes.</p>

  <p>(Although, overall, it's my personal choice)</p>

  <h3>Wrapper script</h3>
  <div>
    <p>Save the following script as <code>vim</code> and make it executable with <code>chmod +x vim</code>.</p>

    <p>Then put it in a directory that's looked up in <code>PATH</code> before the directory
with actual <code>vim</code> binary (e.g. prepend <code>$HOME/.local/bin</code> to <code>PATH</code>).</p>

    <pre><code class="language-sh">#!/usr/bin/env sh

IFS='
'
for dir in "$(echo "$PATH" | tr ":" "\n" | grep -Fxv "$(dirname $0)")"; do
    if [ -x "$dir/vim" ]; then
        exec "$dir/vim" -u "${XDG_CONFIG_HOME:-$HOME/.config}"/vim/vimrc "$@"
    fi
done
</code></pre>

    <p>Doesn't affect Neovim, leaves <code>VIMINIT</code> alone, and works outside shell.
But you need to carry it together with your config and can cause false
positives when checking if Vim is installed.</p>
  </div>

</aside>

<h2 id="configuration-in-vimrc">Configuration in <em>vimrc</em></h2>

<p>First of all, although not mandatory, let's set <code>$MYVIMRC</code> variable:</p>
<pre><code class="language-vim">if empty($MYVIMRC) | let $MYVIMRC = expand('&lt;sfile&gt;:p') | endif
</code></pre>

<p>Let's define fallback locations in case <code>XDG_*</code> variables are not set.</p>
<pre><code class="language-vim">if empty($XDG_CACHE_HOME)  | let $XDG_CACHE_HOME  = $HOME."/.cache"       | endif
if empty($XDG_CONFIG_HOME) | let $XDG_CONFIG_HOME = $HOME."/.config"      | endif
if empty($XDG_DATA_HOME)   | let $XDG_DATA_HOME   = $HOME."/.local/share" | endif
if empty($XDG_STATE_HOME)  | let $XDG_STATE_HOME  = $HOME."/.local/state" | endif
</code></pre>

<p>Let's add entries to <code>runtimepath</code>:</p>
<pre><code class="language-vim">set runtimepath^=$XDG_CONFIG_HOME/vim
set runtimepath+=$XDG_DATA_HOME/vim
set runtimepath+=$XDG_CONFIG_HOME/vim/after
</code></pre>

<p><code>$XDG_CONFIG_HOME/vim</code> and <code>$XDG_CONFIG_HOME/vim/after</code> are just equivalents of
<code>~/.vim</code> and <code>~/.vim/after</code>, but <code>$XDG_DATA_HOME/vim</code> is brand new - there we
will keep downloadables (like plugins and spell files), Netrw bookmarks etc.</p>

<p>Let's set directory for Vim8 build-in packages:</p>
<pre><code class="language-vim">set packpath^=$XDG_DATA_HOME/vim
set packpath+=$XDG_DATA_HOME/vim/after
</code></pre>

<p>Netrw is just as easy:</p>
<pre><code class="language-vim">let g:netrw_home = $XDG_DATA_HOME."/vim"
</code></pre>

<p>What about spellings? Well, this one is more tricky, because it isn't controlled
by any option. Instead, it searches for <code>spell</code> directory in whole runtime path.
If none is found then it falls back to <code>~/.vim/spell</code>. So let's create one at
desired location ourselves!</p>
<pre><code class="language-vim">call mkdir($XDG_DATA_HOME."/vim/spell", 'p', 0700)
</code></pre>

<p>So far so good. We are left with state (backup, undo, swap, viminfo, view).
Vim doesn't create directories for them (even for defaults), so we will need
to do it ourselves - luckily VimL offers <code>mkdir()</code> function:</p>
<pre><code class="language-vim">set backupdir=$XDG_STATE_HOME/vim/backup | call mkdir(&amp;backupdir, 'p', 0700)
set directory=$XDG_STATE_HOME/vim/swap   | call mkdir(&amp;directory, 'p', 0700)
set undodir=$XDG_STATE_HOME/vim/undo     | call mkdir(&amp;undodir,   'p', 0700)
set viewdir=$XDG_STATE_HOME/vim/view     | call mkdir(&amp;viewdir,   'p', 0700)

if !has('nvim') " Neovim has its own location which already complies with XDG specification
  set viminfofile=$XDG_STATE_HOME/vim/viminfo
endif
</code></pre>

<p>Congratulations! <br />
Now your Vim is configured with accordance to XDG Base Directory specification.</p>

<h1 id="sources">Sources</h1>
<ul>
  <li><a href="https://tlvince.com/vim-respect-xdg">Vim respect XDG</a></li>
  <li><a href="https://specifications.freedesktop.org/basedir-spec/0.8/">XDG Base Directory Specification</a></li>
  <li><a href="https://github.com/vim/vim/issues/2034">Issue #2034: [RFC] .config/vim(UNIX), AppData/Roaming/vim(Windows) directory structure</a></li>
  <li><a href="https://github.com/vim/vim/commit/6a459902592e2a4ba68">patch 7.3.1178</a></li>
  <li><a href="https://github.com/vim/vim/commit/c9df1fb">patch 9.1.0327</a></li>
  <li><a href="https://wiki.archlinux.org/index.php/XDG_Base_Directory">XDG Base Directory - ArchWiki</a></li>
  <li><a href="https://groups.google.com/g/vim_dev/c/ieoldm29ymM/m/-dTZ2E8A1xwJ">[PATCH] XDG Base Directory Specification support</a></li>
</ul>]]></content><author><name>Jorenar</name></author><summary type="html"><![CDATA[XDG Base Directory specification, $XDG_CONFIG_HOME etc. Great thing - configs separated from user data and cache, no clutter in home directory. Unfortunately, many programs still don't respect it, including Vim. But what would be our favourite text editor if we wouldn't be able to reconfigure it!]]></summary></entry></feed>