<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Thomashk0's web pages</title><link href="https://thomashk0.github.io/" rel="alternate"></link><link href="https://thomashk0.github.io/feeds/all.atom.xml" rel="self"></link><id>https://thomashk0.github.io/</id><updated>2024-08-25T00:00:00+02:00</updated><entry><title>Some Inkscape Tips</title><link href="https://thomashk0.github.io/posts/2024/08/inkscape-tips/" rel="alternate"></link><published>2024-08-25T00:00:00+02:00</published><updated>2024-08-25T00:00:00+02:00</updated><author><name>Thomas Hiscock</name></author><id>tag:thomashk0.github.io,2024-08-25:/posts/2024/08/inkscape-tips/</id><summary type="html">&lt;p&gt;As a researcher, having some basic knowledge of a vector graphic tool is a valuable skill.
Among the variety of options, &lt;a class="reference external" href="https://inkscape.org/"&gt;Inkscape&lt;/a&gt; is a nice open-source project for creating and editing SVG files.&lt;/p&gt;
&lt;p&gt;This tool is quite powerful, you can do almost any sort of 2-D vector drawing with it …&lt;/p&gt;</summary><content type="html">&lt;p&gt;As a researcher, having some basic knowledge of a vector graphic tool is a valuable skill.
Among the variety of options, &lt;a class="reference external" href="https://inkscape.org/"&gt;Inkscape&lt;/a&gt; is a nice open-source project for creating and editing SVG files.&lt;/p&gt;
&lt;p&gt;This tool is quite powerful, you can do almost any sort of 2-D vector drawing with it.
Such flexibility comes with a cost: there is a steep learning curve for the tool and it can take some efforts to make simple things.&lt;/p&gt;
&lt;p&gt;Is it worth investing time in learning &lt;a class="reference external" href="https://inkscape.org/"&gt;Inkscape&lt;/a&gt;? To be honest, I don't know.
If you need a quick solution to make drawings, you will probably get the job
done faster with things like &lt;a class="reference external" href="https://app.diagrams.net/"&gt;draw.io&lt;/a&gt;,
&lt;a class="reference external" href="https://excalidraw.com"&gt;excalidraw&lt;/a&gt;, or others.&lt;/p&gt;
&lt;p&gt;I learned &lt;a class="reference external" href="https://inkscape.org/"&gt;Inkscape&lt;/a&gt; because it was the best open-source option at the time I
started my career.  But I do not regret it. I like to have an offline
open-source solution for my drawings that is git-friendly. With a bit of
practice, you can produce any kind of diagrams (more that enough for scientific
papers). You will also not be afraid to edit SVG files when needed (e.g.,
stripping a you-don't-know-why-it-is-there margin from matplotlib to make your
paper fit the page limit, 5 minutes before a deadline).&lt;/p&gt;
&lt;p&gt;In this post, I show some tip to improve the &lt;a class="reference external" href="https://inkscape.org/"&gt;Inkscape&lt;/a&gt; experience.&lt;/p&gt;
&lt;div class="section" id="basic-configuration"&gt;
&lt;h2&gt;Basic Configuration&lt;/h2&gt;
&lt;p&gt;For scientific papers, some sort of alignment is always welcome in your
illustrations! If find that &lt;strong&gt;using a grid is mandatory&lt;/strong&gt;.
You want to do two things:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Display the grid (Press &amp;quot;#&amp;quot; for switching it on/off). Note that you can
customize the grid size. There are two grids, primary and secondary. It can
be useful to change the spacing and colors in some situations.&lt;/li&gt;
&lt;li&gt;Enable snapping (Press &amp;quot;%&amp;quot; for switching it on/off), so that items like
boxes or text will automatically snap to the grid. You can customize how
snapping behaves: I find it easier to snap to borders of elements. You want
to enable snapping for all items (boxes, text, paths).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This way, you can ensure consistent spacing of items.&lt;/p&gt;
&lt;div class="figure align-center" id="fig-inkscape-snaping"&gt;
&lt;img alt="Screenshot showing inkscape configuration with grid" src="https://thomashk0.github.io/static/img/screenshot_inkscape_snapping.png" style="width: 80%;" /&gt;
&lt;p class="caption"&gt;Screenshot showing the grid configuration. Aligning items with snapping is
so satisfying :)&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="use-automatic-alignment"&gt;
&lt;h2&gt;Use Automatic Alignment&lt;/h2&gt;
&lt;p&gt;Inkscape has automatic alignment, this feature can save you many clicks! I tend
to draw everything and align everything at the end.&lt;/p&gt;
&lt;p&gt;Press &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;CTRL-ALT-A&lt;/span&gt;&lt;/tt&gt; to open the alignment pane, then you can select items and
align them in different ways.&lt;/p&gt;
&lt;p&gt;The important thing to remember here is that alignment is done on the first
item of the selection.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="copy-style"&gt;
&lt;h2&gt;Copy style&lt;/h2&gt;
&lt;p&gt;You do not want to manually replicate style of items.&lt;/p&gt;
&lt;p&gt;Once you styled an item (box or whatever), you can copy it with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;CTRL-C&lt;/span&gt;&lt;/tt&gt;,
then you can select a bunch of other items and press &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;CTRL-SHIFT-V&lt;/span&gt;&lt;/tt&gt;, this
will apply the style of the first item to your selection.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="conversion"&gt;
&lt;span id="sec-conversion"&gt;&lt;/span&gt;&lt;h2&gt;Conversion&lt;/h2&gt;
&lt;p&gt;For converting SVG to other formats, I usually export the drawing region.
This requires you to properly resize the document to your drawing area.
The Inkscape command is quite handly and has tons of options for exporting
&lt;cite&gt;.svg&lt;/cite&gt; files.&lt;/p&gt;
&lt;p&gt;Export to PDF:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;inkscape&lt;span class="w"&gt; &lt;/span&gt;--export-text-to-path&lt;span class="w"&gt; &lt;/span&gt;-D&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;output.pdf&lt;span class="w"&gt; &lt;/span&gt;input.svg
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;--export-text-to-path&lt;/span&gt;&lt;/tt&gt; option is very important. As suggested, it
transforms text to paths. Otherwise, text is rendered by the PDF rendering
engine and fonts may be missing. By passing this flag, you will have a
consistent rendering of your drawings.&lt;/p&gt;
&lt;p&gt;Export to PNG:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;inkscape&lt;span class="w"&gt; &lt;/span&gt;-D&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;300&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;output.png&lt;span class="w"&gt; &lt;/span&gt;input.svg
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here, the DPI parameter is set &lt;tt class="docutils literal"&gt;300&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;With release 1.0, the Inkscape command line changed. Here are the versions
of those commands for older Inkscape:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;inkscape&lt;span class="w"&gt; &lt;/span&gt;--export-text-to-path&lt;span class="w"&gt; &lt;/span&gt;-D&lt;span class="w"&gt; &lt;/span&gt;-A&lt;span class="w"&gt; &lt;/span&gt;output.pdf&lt;span class="w"&gt; &lt;/span&gt;input.svg
&lt;span class="gp"&gt;$ &lt;/span&gt;inkscape&lt;span class="w"&gt; &lt;/span&gt;-D&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;300&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-e&lt;span class="w"&gt; &lt;/span&gt;output.png&lt;span class="w"&gt; &lt;/span&gt;input.svg
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="makefile-snippet"&gt;
&lt;h2&gt;Makefile Snippet&lt;/h2&gt;
&lt;p&gt;A big selling point for &lt;a class="reference external" href="https://inkscape.org/"&gt;Inkscape&lt;/a&gt; is that you can save your &lt;tt class="docutils literal"&gt;.svg&lt;/tt&gt; files
inside a git repository and generate exports at build-time using the commands
shown in the &lt;a class="reference external" href="#sec-conversion"&gt;previous section&lt;/a&gt;. This is super convenient
for scientific papers.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Once you generate a final version of your paper, I highly recommend saving
the figures in some way (I usually add them to git). Inkscape updates can
change the rendering. This happened to me several time: the layout of your
paper is completely broken because the images generated are not exactly the
same (e.g., extra margin).&lt;/p&gt;
&lt;p class="last"&gt;Then, if you want to be 100% reproducible, snapshot your exported figures!&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Here is a snippet that you can integrate in your makefile to automatically build figures.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;.svg&lt;/tt&gt; source files are assumed to be in directory &lt;tt class="docutils literal"&gt;figs/svg/&lt;/tt&gt;.&lt;/li&gt;
&lt;li&gt;Type &lt;tt class="docutils literal"&gt;make figs/name_of_fig.pdf&lt;/tt&gt; to compile &lt;tt class="docutils literal"&gt;name_of_fig.pdf&lt;/tt&gt; into PDF.&lt;/li&gt;
&lt;li&gt;Type &lt;tt class="docutils literal"&gt;make figs/name_of_fig.png&lt;/tt&gt; to compile &lt;tt class="docutils literal"&gt;name_of_fig.png&lt;/tt&gt; into PNG.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nv"&gt;INKSCAPE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;?=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;inkscape
&lt;span class="nv"&gt;INKSCAPE_FLAGS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;?=&lt;/span&gt;
&lt;span class="nv"&gt;INKSCAPE_FLAGS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;--export-text-to-path
&lt;span class="nv"&gt;INKSCAPE_VERSION_1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;shell&lt;span class="w"&gt; &lt;/span&gt;inkscape&lt;span class="w"&gt; &lt;/span&gt;--version&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;grep&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;-E&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Inkscape 1\.[0-9]+&amp;#39;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;figs/%.pdf&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;figs&lt;/span&gt;/&lt;span class="n"&gt;svg&lt;/span&gt;/%.&lt;span class="n"&gt;svg&lt;/span&gt;
&lt;span class="cp"&gt;ifeq ($(INKSCAPE_VERSION_1),) # Inkscape &amp;lt; 1.0&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;INKSCAPE&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;INKSCAPE_FLAGS&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-D&lt;span class="w"&gt; &lt;/span&gt;-A&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$@&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;$&amp;lt;
&lt;span class="cp"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;INKSCAPE&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;INKSCAPE_FLAGS&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-D&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$@&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;$&amp;lt;
&lt;span class="cp"&gt;endif&lt;/span&gt;

&lt;span class="nf"&gt;figs/%.png&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;figs&lt;/span&gt;/&lt;span class="n"&gt;svg&lt;/span&gt;/%.&lt;span class="n"&gt;svg&lt;/span&gt;
&lt;span class="cp"&gt;ifeq ($(INKSCAPE_VERSION_1),) # Inkscape &amp;lt; 1.0&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;INKSCAPE&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;INKSCAPE_FLAGS&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-D&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;300&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-e&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$@&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;$&amp;lt;
&lt;span class="cp"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;INKSCAPE&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;INKSCAPE_FLAGS&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-D&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;300&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$@&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;$&amp;lt;
&lt;span class="cp"&gt;endif&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="hiding-layers-for-simple-animations"&gt;
&lt;h2&gt;Hiding Layers for Simple Animations&lt;/h2&gt;
&lt;p&gt;You can organize your &lt;cite&gt;.svg&lt;/cite&gt; file into multiple layer.&lt;/p&gt;
&lt;p&gt;Sometimes, it can be nice to export only some selected layers.
Imagine a file having some background image and some layers containing arrows and text annotations.
By exporting a subset of layers, it is possible to create an animation that you can include in a slide deck for example.&lt;/p&gt;
&lt;p&gt;I have a small script &lt;a class="reference external" href="https://github.com/thomashk0/blog/tree/main/inkscape-export-layers"&gt;here&lt;/a&gt; (~100 lines of Python, without any external dependency) that I use all the time.&lt;/p&gt;
&lt;p&gt;Hiding some layers is as simple as:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="go"&gt;./exportlayers --hide text_layer_1,text_layer_2 -o fig_background_only.pdf fig.svg&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="making-you-diagram-draw-io-ish"&gt;
&lt;h2&gt;Making you diagram &lt;tt class="docutils literal"&gt;draw.io&lt;/tt&gt;-ish&lt;/h2&gt;
&lt;p&gt;If you are afraid that your diagrams will not look as cool as those of your friends made with &lt;tt class="docutils literal"&gt;draw.io&lt;/tt&gt;,
here are a few tips to mimic the draw.io style:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Enable rounding of borders in &amp;quot;Stroke style&amp;quot;, even add a small radius to the corner of boxes.&lt;/li&gt;
&lt;li&gt;Make your borders the same colors of the boxes, but make them slightly darker:
show colors in HSL, and reduce the lightness (L).&lt;/li&gt;
&lt;li&gt;Pick a &amp;quot;good-looking&amp;quot; color palette on google and stick to it for your project.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="figure align-center"&gt;
&lt;img alt="Screenshot showing a styled diagram" src="https://thomashk0.github.io/static/img/screenshot_inkscape_drawio.png" style="width: 80%;" /&gt;
&lt;p class="caption"&gt;Restyling of the diagram shown in &lt;a class="reference external" href="#fig-inkscape-snaping"&gt;previous section&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><category term="tooling"></category><category term="tooling"></category></entry><entry><title>Ray Tracing and Refraction</title><link href="https://thomashk0.github.io/posts/2022/12/raytracing-refraction/" rel="alternate"></link><published>2022-12-28T00:00:00+01:00</published><updated>2022-12-28T00:00:00+01:00</updated><author><name>Thomas Hiscock</name></author><id>tag:thomashk0.github.io,2022-12-28:/posts/2022/12/raytracing-refraction/</id><summary type="html">&lt;p&gt;A few weeks ago I was following Peter Shirley’s awesome &lt;a class="reference external" href="https://raytracing.github.io/books/RayTracingInOneWeekend.html"&gt;“Ray Tracing in One
Week End”&lt;/a&gt;
book. Everything went fine until I reached dielectric materials, where I
started to obtain really weird pictures. From there, I had to fully re-check
the ray tracer.  This was both painful and beneficial …&lt;/p&gt;</summary><content type="html">&lt;p&gt;A few weeks ago I was following Peter Shirley’s awesome &lt;a class="reference external" href="https://raytracing.github.io/books/RayTracingInOneWeekend.html"&gt;“Ray Tracing in One
Week End”&lt;/a&gt;
book. Everything went fine until I reached dielectric materials, where I
started to obtain really weird pictures. From there, I had to fully re-check
the ray tracer.  This was both painful and beneficial, since it forced me to
dig into every details of the ray tracer. The formulas for refraction are not
really explained in the book. So, I decided to write a more detailed
explanation in this post. Internalizing this proof actually lead me to the bug
in my code, I hope that can help.&lt;/p&gt;
&lt;p&gt;Here is a small widget that implements the formulas described in this post.&lt;/p&gt;
&lt;div class="demo-form"&gt;
    &lt;table&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;label for="ni"&gt;Refractive Indice ni&lt;/label&gt;&lt;/td&gt;
            &lt;td&gt;&lt;input type="text" id="ni" value="1" /&gt;&lt;/td&gt;
            &lt;td&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;label for="nr"&gt;Refractive Indice nr&lt;/label&gt;&lt;/td&gt;
            &lt;td&gt;&lt;input type="text" id="nr" value="1.6" /&gt;&lt;/td&gt;
            &lt;td&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;label for="angle"&gt;Angle In&lt;/label&gt;&lt;/td&gt;
            &lt;td&gt;&lt;input type="range" id="angle" name="angle" value="40" min="0" max="90" step="0.1" /&gt;&lt;/td&gt;
            &lt;td&gt;&lt;span id="angle-value"&gt;40&amp;#176;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;Angle Out&lt;/td&gt;
            &lt;td&gt;&lt;/td&gt;
            &lt;td align="right"&gt;&lt;span id="angle-out"&gt;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/table&gt;
    &lt;div id="svg-canvas" class="svg-container"&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="section" id="overview"&gt;
&lt;h2&gt;Overview&lt;/h2&gt;
&lt;p&gt;Refraction describes how a ray behaves when crossing materials. We
consider the setup depicted on &lt;a class="reference external" href="#fig-refraction"&gt;Figure 1&lt;/a&gt;,
where a ray intersects different materials (e.g., from air to water).
The materials have different refractive indices &lt;span class="math"&gt;\(n_{i}\)&lt;/span&gt; and
&lt;span class="math"&gt;\(n_{r}\)&lt;/span&gt;. Let &lt;span class="math"&gt;\(\vec{i}\)&lt;/span&gt; be the incident ray, &lt;span class="math"&gt;\(\vec{r}\)&lt;/span&gt;
the refracted ray and &lt;span class="math"&gt;\(\vec{n}\)&lt;/span&gt; the surface normal. The question
is: how can we express &lt;span class="math"&gt;\(\vec{r}\)&lt;/span&gt; in function of &lt;span class="math"&gt;\(\vec{i}\)&lt;/span&gt;
and &lt;span class="math"&gt;\(\vec{n}\)&lt;/span&gt; and the refractive indices?&lt;/p&gt;
&lt;div class="figure align-center" id="fig-refraction"&gt;
&lt;img alt="Typical Refraction Setup" src="https://thomashk0.github.io/static/img/raytracer_refraction.png" style="width: 65%;" /&gt;
&lt;p class="caption"&gt;Figure 1: Typical Refraction Setup&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;We make the following assumptions:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;the normal vector is always oriented against the incident ray,
formally &lt;span class="math"&gt;\(\langle\vec{i},\,\vec{n}\rangle&amp;lt;0\)&lt;/span&gt;,&lt;/li&gt;
&lt;li&gt;all vectors are normalized,
&lt;span class="math"&gt;\(\|\vec{i}\|=\|\vec{r}\|=\|\vec{n}\|=1\)&lt;/span&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The relation between &lt;span class="math"&gt;\(\theta_{i}\)&lt;/span&gt; and &lt;span class="math"&gt;\(\theta_{r}\)&lt;/span&gt; is given
by Snell’s law, which states that:&lt;/p&gt;
&lt;div class="math"&gt;
\begin{equation*}
n_{i}\sin\theta_{i}=n_{r}\sin\theta_{r}\label{eq:snell_law}
\end{equation*}
&lt;/div&gt;
&lt;p&gt;Note that there cannot be refraction in every configuration. For
refraction to be possible, we need to have:&lt;/p&gt;
&lt;div class="math"&gt;
\begin{equation*}
\frac{n_{i}}{n_{r}}\sin\theta_{i}&amp;lt;1.
\end{equation*}
&lt;/div&gt;
&lt;p&gt;When this condition is not satisfied, the ray is reflected.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-refraction-formula"&gt;
&lt;h2&gt;The Refraction Formula&lt;/h2&gt;
&lt;p&gt;Ok, now lets see how we can compute &lt;span class="math"&gt;\(\vec{r}\)&lt;/span&gt; from &lt;span class="math"&gt;\(\vec{i}\)&lt;/span&gt;
and &lt;span class="math"&gt;\(\vec{n}\)&lt;/span&gt;. The trick is to decompose &lt;span class="math"&gt;\(\vec{r}\)&lt;/span&gt; as
follows:&lt;/p&gt;
&lt;div class="math"&gt;
\begin{equation*}
\vec{r}=\vec{r_{||}}+\vec{r_{\perp}}
\end{equation*}
&lt;/div&gt;
&lt;p&gt;Where is &lt;span class="math"&gt;\(\vec{r}_{||}\)&lt;/span&gt; is the projection of &lt;span class="math"&gt;\(\vec{r}\)&lt;/span&gt; on
&lt;span class="math"&gt;\(\vec{n}\)&lt;/span&gt; and &lt;span class="math"&gt;\(\vec{r_{\perp}}\)&lt;/span&gt; the projection on the
orthogonal of &lt;span class="math"&gt;\(\vec{n}\)&lt;/span&gt; in the plane generated by &lt;span class="math"&gt;\(\vec{i}\)&lt;/span&gt;
and &lt;span class="math"&gt;\(\vec{n}\)&lt;/span&gt; . This decomposition expands as follows:&lt;/p&gt;
&lt;div class="math"&gt;
\begin{equation*}
\begin{aligned}
\vec{r} &amp;amp; = &amp;amp; \underbrace{\langle\vec{r},\,\vec{n}\rangle\vec{n}}_{\vec{r_{||}}}+\underbrace{(\vec{r}-\langle\vec{r},\,\vec{n}\rangle\vec{n})}_{\vec{r_{\perp}}}\label{eq:r_expansion}\end{aligned}
\end{equation*}
&lt;/div&gt;
&lt;p&gt;It is easy to check that the right term is indeed orthogonal to
&lt;span class="math"&gt;\(\vec{n}\)&lt;/span&gt; (the dot product with &lt;span class="math"&gt;\(\vec{n}\)&lt;/span&gt; is zero). Another
way to express &lt;span class="math"&gt;\(\vec{r}_{\perp}\)&lt;/span&gt; is through a cross product:&lt;/p&gt;
&lt;div class="math"&gt;
\begin{equation*}
\vec{r}_{\perp}=(\vec{r}-\langle\vec{r},\,\vec{n}\rangle\vec{n})=(\vec{r}\times\vec{n})\times\vec{n}.
\end{equation*}
&lt;/div&gt;
&lt;p&gt;We can expand &lt;span class="math"&gt;\(\vec{i}\)&lt;/span&gt; in the same way we did for
&lt;span class="math"&gt;\(\vec{r}\)&lt;/span&gt;.&lt;/p&gt;
&lt;div class="math"&gt;
\begin{equation*}
\begin{aligned}
\vec{i} &amp;amp; = &amp;amp; \underbrace{\langle\vec{i},\,\vec{n}\rangle\vec{n}}_{\vec{i_{||}}}+\underbrace{(\vec{i}-\langle\vec{i},\,\vec{n}\rangle\vec{n})}_{\vec{i_{\perp}}}\end{aligned}
\end{equation*}
&lt;/div&gt;
&lt;p&gt;And we also have (keep this equality in mind, we will reuse it by the
end of the proof):&lt;/p&gt;
&lt;div class="math" id="equation1"&gt;
\begin{equation*}
\vec{i}_{\perp}=(\vec{i}-\langle\vec{i},\,\vec{n}\rangle\vec{n})=(\vec{i}\times\vec{n})\times\vec{n}\label{eq:i_perp}
\end{equation*}
&lt;/div&gt;
&lt;p&gt;Now here is the trick I missed when trying to work out this proof:
&lt;span class="math"&gt;\(\vec{r}\)&lt;/span&gt; is in the plane generated by &lt;span class="math"&gt;\(\vec{i}\)&lt;/span&gt; and
&lt;span class="math"&gt;\(\vec{n}\)&lt;/span&gt;. In other words, &lt;span class="math"&gt;\(\vec{i}\times\vec{n}\)&lt;/span&gt; and
&lt;span class="math"&gt;\(\vec{r}\times\vec{n}\)&lt;/span&gt; are colinear and as a bonus, they are
linked by Snell’s law. The cross product of two vector is defined as:&lt;/p&gt;
&lt;div class="math"&gt;
\begin{equation*}
\vec{i}\times\vec{n}=\|\vec{i}\|\|\vec{n}\|\sin\theta_{i}\vec{k}.
\end{equation*}
&lt;/div&gt;
&lt;p&gt;Here, I introduced &lt;span class="math"&gt;\(\vec{k}\)&lt;/span&gt; which is the orthogonal vector to the
plane generated by &lt;span class="math"&gt;\(\vec{i}\)&lt;/span&gt; and &lt;span class="math"&gt;\(\vec{n}\)&lt;/span&gt;. Similarly, for
&lt;span class="math"&gt;\(\vec{r}\)&lt;/span&gt; we have:&lt;/p&gt;
&lt;div class="math"&gt;
\begin{equation*}
\vec{r}\times\vec{n}=\|\vec{r}\|\|\vec{n}\|\sin\theta_{r}\vec{k}.
\end{equation*}
&lt;/div&gt;
&lt;p&gt;If we assume that &lt;span class="math"&gt;\(\|\vec{i}\|=\|\vec{r}\|=1\)&lt;/span&gt;, we can write:&lt;/p&gt;
&lt;div class="math"&gt;
\begin{equation*}
\begin{aligned}
\vec{r}\times\vec{n} &amp;amp; =\sin\theta_{r}\vec{k}\nonumber \\
 &amp;amp; =\frac{n_{i}}{n_{r}}\sin\theta_{i}\vec{k} &amp;amp; \text{(Using Snell's law)}\nonumber \\
 &amp;amp; =\frac{n_{i}}{n_{r}}\vec{i}\times\vec{n}.\end{aligned}
\end{equation*}
&lt;/div&gt;
&lt;p&gt;Awesome! We are ready to expand &lt;span class="math"&gt;\(\vec{r}\)&lt;/span&gt;. Lets review the
decomposition of &lt;span class="math"&gt;\(\vec{r}\)&lt;/span&gt;:&lt;/p&gt;
&lt;div class="math"&gt;
\begin{equation*}
\begin{aligned}
\vec{r} &amp;amp; = &amp;amp; \vec{r}_{||} + \vec{r}_{\perp}\\
        &amp;amp; = &amp;amp; \langle\vec{r},\,\vec{n}\rangle\vec{n}+(\vec{r}\times\vec{n})\times\vec{n}.\end{aligned}
\end{equation*}
&lt;/div&gt;
&lt;p&gt;We can now expand each term. Lets start with the left one,
&lt;span class="math"&gt;\(\vec{r}_{||}\)&lt;/span&gt;:&lt;/p&gt;
&lt;div class="math"&gt;
\begin{equation*}
\begin{aligned}
\langle\vec{r},\,\vec{n}\rangle\vec{n} &amp;amp; =-\langle-\vec{r},\,\vec{n}\rangle\vec{n}\\
 &amp;amp; =-\cos\theta_{r}\vec{n}\\
 &amp;amp; =-\sqrt{1-\sin^{2}\theta_{r}}\vec{n}\\
 &amp;amp; =-\sqrt{1-\left(\frac{n_{i}}{n_{\theta}}\right)^{2}\sin^{2}\theta_{i}}\vec{n}\\
 &amp;amp; =-\sqrt{1-\left(\frac{n_{i}}{n_{\theta}}\right)^{2}\left(1-\cos^{2}\theta_{i}\right)}\vec{n}\\
 &amp;amp; =-\sqrt{1-\left(\frac{n_{i}}{n_{\theta}}\right)^{2}\left(1-\langle-\vec{i},\,\vec{n}\rangle^{2}\right)}\vec{n}\end{aligned}
\end{equation*}
&lt;/div&gt;
&lt;p&gt;In the first line, we use the basic trigonometry equation between sines
and cosines, &lt;span class="math"&gt;\(\cos^{2}\theta+\sin^{2}\theta=1\)&lt;/span&gt;. In the second
line, we apply Snell law. In the third line, we apply again some basic
trigonometry again. The last step uses the fact that
&lt;span class="math"&gt;\(\cos\theta_{i}=\langle-\vec{i},\,\vec{n}\rangle\)&lt;/span&gt;. So, we have
expressed &lt;span class="math"&gt;\(\vec{r_{\perp}}\)&lt;/span&gt; only from &lt;span class="math"&gt;\(\vec{i}\)&lt;/span&gt; and
&lt;span class="math"&gt;\(\vec{n}\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Now, it is time to expand &lt;span class="math"&gt;\(\vec{r_{\perp}}\)&lt;/span&gt;: .&lt;/p&gt;
&lt;div class="math"&gt;
\begin{equation*}
\begin{aligned}
(\vec{r}\times\vec{n})\times\vec{n} &amp;amp; =\left(\frac{n_{i}}{n_{r}}\vec{i}\times\vec{n}\right)\times\vec{n}\\
 &amp;amp; =\frac{n_{i}}{n_{r}}\left(\vec{i}\times\vec{n}\right)\times\vec{n}\\
 &amp;amp; =\frac{n_{i}}{n_{r}}(\vec{i}-\langle\vec{i},\,\vec{n}\rangle\vec{n})\\
 &amp;amp; =\frac{n_{i}}{n_{r}}(\vec{i}+\langle-\vec{i},\,\vec{n}\rangle\vec{n})\end{aligned}
\end{equation*}
&lt;/div&gt;
&lt;p&gt;On the first line, we rewrite the cross product, thanks to Snell's law. On the second line, we move out
the scalar constant and on the last line, we use the relation &lt;a class="reference external" href="#equation1"&gt;shown previously&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Lets define &lt;span class="math"&gt;\(\mu=\frac{n_{i}}{n_{r}}\)&lt;/span&gt;, then &lt;span class="math"&gt;\(\vec{r}\)&lt;/span&gt; can be
written as:&lt;/p&gt;
&lt;div class="math"&gt;
\begin{equation*}
\begin{aligned}
\vec{r} &amp;amp; =\vec{r_{||}}+\vec{r}_{\perp}\\
 &amp;amp; =-\sqrt{1-\mu^{2}\left(1-\langle-\vec{i},\,\vec{n}\rangle^{2}\right)}\vec{n}+\mu(\vec{i}+\langle-\vec{i},\,\vec{n}\rangle\vec{n})\\
 &amp;amp; =\left(\mu\langle-\vec{i},\,\vec{n}\rangle-\sqrt{1-\mu^{2}\left(1-\langle-\vec{i},\,\vec{n}\rangle^{2}\right)}\right)\vec{n}+\mu\vec{i} \end{aligned}
\end{equation*}
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="back-to-the-code"&gt;
&lt;h2&gt;Back to the Code&lt;/h2&gt;
&lt;p&gt;Now, the code shown &lt;a class="reference external" href="https://raytracing.github.io/books/RayTracingInOneWeekend.html#dielectrics/refraction"&gt;in the book&lt;/a&gt; should make more sense.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;vec3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;refract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vec3&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;uv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vec3&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;etai_over_etat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;auto&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cos_theta&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fmin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;uv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;vec3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r_out_perp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;etai_over_etat&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uv&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cos_theta&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;vec3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r_out_parallel&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fabs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r_out_perp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length_squared&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r_out_perp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r_out_parallel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Well, if you look carefully, the &lt;tt class="docutils literal"&gt;r_out_parallel&lt;/tt&gt; does not match with the expression of &lt;span class="math"&gt;\(\vec{r}_{||}\)&lt;/span&gt;.
The author applied Pythagoras' theorem (assuming the vector returned is a unit vector).&lt;/p&gt;
&lt;div class="math"&gt;
\begin{equation*}
||\vec{r}||^2 = ||\vec{r}_{||}||^2 + ||\vec{r}_{\perp}||^2
\end{equation*}
&lt;/div&gt;
&lt;p&gt;So,&lt;/p&gt;
&lt;div class="math"&gt;
\begin{equation*}
||\vec{r}_{||}|| = \pm \sqrt{1 -  ||\vec{r}_{\perp}||^2}
\end{equation*}
&lt;/div&gt;
&lt;p&gt;Since we know that &lt;span class="math"&gt;\(\vec{r}_{||}\)&lt;/span&gt; is oriented against &lt;span class="math"&gt;\(\vec{n}\)&lt;/span&gt;, we can write:&lt;/p&gt;
&lt;div class="math"&gt;
\begin{equation*}
\vec{r}_{||} = -\sqrt{1 -  ||\vec{r}_{\perp}||^2}\vec{n}
\end{equation*}
&lt;/div&gt;
&lt;p&gt;Pfew, while there are no fancy math involved, understanding the final refraction program was much more involved than what I initially though.
Given the quantity of boring equation, I definitely understand why the author did not include them in its book!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="useful-references"&gt;
&lt;h2&gt;Useful References&lt;/h2&gt;
&lt;p&gt;Here are some references that helped me debug refraction:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://vertexwahn.de/2020/12/19/refraction/"&gt;Ray tracing 101: Refraction of Light&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://psgraphics.blogspot.com/2020/12/debugging-refraction-in-ray-tracer.html"&gt;Debugging refraction in a ray tracer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;script type='text/javascript'&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/latest.js?config=TeX-AMS-MML_HTMLorMML';

    var configscript = document.createElement('script');
    configscript.type = 'text/x-mathjax-config';
    configscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'none' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        availableFonts: ['STIX', 'TeX']," +
        "        preferredFont: 'STIX'," +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";

    (document.body || document.getElementsByTagName('head')[0]).appendChild(configscript);
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="graphics"></category><category term="programming"></category><category term="graphics"></category></entry><entry><title>Survival Kit for C Programmers (Macros)</title><link href="https://thomashk0.github.io/posts/2022/11/c-survival-macros/" rel="alternate"></link><published>2022-11-24T00:00:00+01:00</published><updated>2022-11-30T00:00:00+01:00</updated><author><name>Thomas Hiscock</name></author><id>tag:thomashk0.github.io,2022-11-24:/posts/2022/11/c-survival-macros/</id><summary type="html">&lt;p&gt;I realized that in my C projects I always need the same macros over and over.
I thought it would be interesting to centralize them somewhere and document them.&lt;/p&gt;
&lt;p&gt;The macros presented here should work with any recent GCC or LLVM compiler.
I do not guarantee they will work on …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I realized that in my C projects I always need the same macros over and over.
I thought it would be interesting to centralize them somewhere and document them.&lt;/p&gt;
&lt;p&gt;The macros presented here should work with any recent GCC or LLVM compiler.
I do not guarantee they will work on all compiler/architectures.&lt;/p&gt;
&lt;p&gt;If you want to go further, I highly recommend you to take a look at the &lt;a class="reference external" href="https://nemequ.github.io/hedley/"&gt;Hedley project&lt;/a&gt;.
Hedley provides a huge amount of features and is platform generic.&lt;/p&gt;
&lt;p&gt;The code for this post (with some additional examples) is available &lt;a class="reference external" href="https://github.com/thomashk0/c-snippets/blob/main/survival/survival.h"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;div class="section" id="sizeof-arrays"&gt;
&lt;h2&gt;Sizeof Arrays&lt;/h2&gt;
&lt;p&gt;One lacking feature in C is the ability to retrieve the size of fixed-size arrays.
The glorious &lt;tt class="docutils literal"&gt;sizeof&lt;/tt&gt; operator, returns the full length in bytes of the target object.
The &lt;tt class="docutils literal"&gt;COUNT_OF&lt;/tt&gt; macro shown below solves this issue.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;/// Retrieve the number of items in a array.&lt;/span&gt;
&lt;span class="cp"&gt;#define COUNT_OF(x) (sizeof(x) / sizeof(x[0]))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can use it as follows:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;local_array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="n"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;COUNT_OF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;local_array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;COUNT_OF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;local_array&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// do some stuff.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If compatibility with C++ is needed, I suggest you pick a safer version of this macro (see this &lt;a class="reference external" href="https://stackoverflow.com/a/4415646"&gt;stack overflow post&lt;/a&gt;).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="basic-type-generic-operations"&gt;
&lt;h2&gt;Basic Type Generic Operations&lt;/h2&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;MIN&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;MAX&lt;/tt&gt; emulates a type generic min and max operations between two variables.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#define MIN(a, b) ((a) &amp;gt; (b)) ? (b) : (a)&lt;/span&gt;
&lt;span class="cp"&gt;#define MAX(a, b) ((a) &amp;lt; (b)) ? (b) : (a)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Another useful one is &lt;tt class="docutils literal"&gt;ABS&lt;/tt&gt;, which emulates a type generic absolute value.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#define ABS(x) (((x) &amp;lt; 0) ? -(x) : (x))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Another function that appears quite frequently in my code bases is a check for
a power of two. It can be implemented with some bit tricks.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#define is_power_of_two(x) ((x) &amp;amp;&amp;amp; !((x) &amp;amp; ((x)-1)))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="compiler-hints"&gt;
&lt;h2&gt;Compiler Hints&lt;/h2&gt;
&lt;p&gt;There are countless compiler-specific macros that allow to give optimization
hints. I only include the ones I use in almost every project.&lt;/p&gt;
&lt;p&gt;The most useful ones are &lt;tt class="docutils literal"&gt;LIKELY&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;UNLIKELY&lt;/tt&gt;, used to indicate the
compiler the expected outcome of a boolean expression.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#define LIKELY(x) __builtin_expect((x), 1)&lt;/span&gt;

&lt;span class="cp"&gt;#define UNLIKELY(x) __builtin_expect((x), 0)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I am not entirely sure that the compiler will always consider those
annotations. I generally use them in two situations.&lt;/p&gt;
&lt;p&gt;The first situation is in performance critical code, where I want to suggest
&amp;quot;really hard&amp;quot; to the compiler what is the hot path in our program. It is worth
mentioning that a better approach for large codebases may be to use &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Profile-guided_optimization"&gt;profile guided optimizations&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The second situation, is when I am doing error checks. I find those annotations
conveniently document the unlikely nature of failures.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;foo_can_fail&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UNLIKELY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bar_acuda&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;-1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UNLIKELY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bar_tabac&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;-2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Another macro I use very often is &lt;tt class="docutils literal"&gt;ALIGNED&lt;/tt&gt;, mostly to align &amp;quot;important&amp;quot; data
on cache line boundaries.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#define ALIGNED(x) __attribute__((aligned(x)))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can use it as follows:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;// In variable declaration.&lt;/span&gt;
&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ALIGNED&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{};&lt;/span&gt;

&lt;span class="c1"&gt;// In structure definition.&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;coords&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ALIGNED&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Another powerful macro is &lt;tt class="docutils literal"&gt;ASSUME&lt;/tt&gt;, we give it predicate that the
compiler can exploit in its optimizations phases.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#define ASSUME(cond)                  \&lt;/span&gt;
&lt;span class="cp"&gt;    do {                              \&lt;/span&gt;
&lt;span class="cp"&gt;        if (!(cond))                  \&lt;/span&gt;
&lt;span class="cp"&gt;            __builtin_unreachable();  \&lt;/span&gt;
&lt;span class="cp"&gt;    } while (0)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I typically use this macro to specify constraints on array sizes, to make loop
optimizations (unrolling, auto-vectorization) more aggressive. For example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;add_vec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data_len&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;ASSUME&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data_len&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;ASSUME&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;data_len&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data_len&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here is a side-by-side comparison of the assembly code (&lt;tt class="docutils literal"&gt;gcc &lt;span class="pre"&gt;-O3&lt;/span&gt;&lt;/tt&gt;) with and
without the &lt;tt class="docutils literal"&gt;ASSUME&lt;/tt&gt; annotation. It is pretty clear that the &lt;tt class="docutils literal"&gt;ASSUME&lt;/tt&gt; macro
allowed to drastically simplify the loop.&lt;/p&gt;
&lt;object data="https://thomashk0.github.io/static/img/c_macro_assume_example.svg" style="width: 100%;" type="image/svg+xml"&gt;Assembly code with and without the ASSUME macro.&lt;/object&gt;
&lt;p&gt;But be careful with &lt;tt class="docutils literal"&gt;ASSUME&lt;/tt&gt;, it is very easy to shoot yourself in the foot
with this macro!  If the assumption given to the compiler is not true, bad
things will happen.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="minimalistic-logging"&gt;
&lt;h2&gt;Minimalistic Logging&lt;/h2&gt;
&lt;p&gt;This topic will be covered in greater details in another post.&lt;/p&gt;
&lt;p&gt;I like to have really simple &lt;tt class="docutils literal"&gt;printf&lt;/tt&gt;-based tracing in my applications
(usually enable only in debug builds).&lt;/p&gt;
&lt;p&gt;Basically, I write a simple wrapper around &lt;tt class="docutils literal"&gt;fprintf&lt;/tt&gt; with the following prototype:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="nf"&gt;survival_log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;long&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;long&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;...)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;__attribute__&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A minimal implementation of this function will look something like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;stdarg.h&amp;gt;&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="nf"&gt;survival_log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;long&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;long&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;...)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;va_list&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arglist&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;[%ld](%s:%ld in %s) &amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;va_start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arglist&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;vfprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arglist&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;va_end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arglist&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The code may look complex because of variadic arguments, but it is not.  What
it does is: first call &lt;tt class="docutils literal"&gt;fprintf&lt;/tt&gt; to print a prefix (log level, file, line)
and then forwards the remaining arguments to &lt;tt class="docutils literal"&gt;vfprintf&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Having this &lt;tt class="docutils literal"&gt;survival_log&lt;/tt&gt; implemented, I define macros that behave as a
regular &lt;tt class="docutils literal"&gt;printf&lt;/tt&gt;. Under the hoods, they just forward their arguments to
&lt;tt class="docutils literal"&gt;survival_log&lt;/tt&gt;.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;DPRINTF&lt;/tt&gt; for debug messages.&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;WPRINTF&lt;/tt&gt; for warning messages.&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;EPRINTF&lt;/tt&gt; for error messages.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example &lt;tt class="docutils literal"&gt;DPRINTF&lt;/tt&gt; can be defined as:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#define DPRINTF(...)                                                         \&lt;/span&gt;
&lt;span class="cp"&gt;    do {                                                                     \&lt;/span&gt;
&lt;span class="cp"&gt;        survival_log(                                                        \&lt;/span&gt;
&lt;span class="cp"&gt;            SURVIVAL_LOG_DEBUG, __FILE__, __func__, __LINE__, __VA_ARGS__);  \&lt;/span&gt;
&lt;span class="cp"&gt;    } while (0)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can use those macros as a regular &lt;tt class="docutils literal"&gt;printf&lt;/tt&gt;. For example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;DPRINTF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;checking LIKELY, UNLIKELY&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LIKELY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rnd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;DPRINTF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;rand() is &amp;gt; 0, (%d)&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rnd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Will produce the following output on &lt;tt class="docutils literal"&gt;stderr&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[debug](survival_demo.c:90 in main) checking LIKELY, UNLIKELY
[debug](survival_demo.c:93 in main) rand() is &amp;gt; 0, (1804289383)
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This logging system is a very good start for small projects.  Despite its
simplicity, I find it very effective in practice.  Furthermore, it is very easy
to extend if needed (e.g., display timestamps, implement filters, log to files,
...).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="scoped-variables"&gt;
&lt;h2&gt;Scoped Variables&lt;/h2&gt;
&lt;p&gt;Again, this topic will be covered in greater details in another post.&lt;/p&gt;
&lt;p&gt;When possible I like to use the &lt;tt class="docutils literal"&gt;__cleanup__&lt;/tt&gt; attribute available in GCC and Clang.
This extension allows to implement automatic cleanup of variables (some sort of RAII in C).&lt;/p&gt;
&lt;p&gt;Put shortly, if a variable is marked with this attribute:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;__attribute__&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;__cleanup__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;int_cleanup&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then, the function &lt;tt class="docutils literal"&gt;void int_cleanup(int* ptr)&lt;/tt&gt; will be called, when variable
&lt;tt class="docutils literal"&gt;x&lt;/tt&gt; goes out of scope.  The address of &lt;tt class="docutils literal"&gt;x&lt;/tt&gt; is passed to &lt;tt class="docutils literal"&gt;int_cleanup&lt;/tt&gt; as
first arguments.&lt;/p&gt;
&lt;p&gt;So with attribute, you can automatically release pointers, close files, etc.&lt;/p&gt;
&lt;p&gt;However, those annotations quickly make code unreadable.
Thus, the first thing to do is to simplify the attribute annotation:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#define SURVIVAL_CLEANUP(func) __attribute__((cleanup(func)))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Basically for each type, I define a &lt;tt class="docutils literal"&gt;scoped_[mytype]&lt;/tt&gt; macro:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#define scoped_int SURVIVAL_CLEANUP(int_cleanup)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then, I would create scoped variable with this macros:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;// __attribute__ ((__cleanup__(int_cleanup))) int x = 42;&lt;/span&gt;
&lt;span class="c1"&gt;// becomes:&lt;/span&gt;
&lt;span class="n"&gt;scoped_int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We could also think of a &lt;tt class="docutils literal"&gt;scoped_int&lt;/tt&gt; macro that would expand to &lt;tt class="docutils literal"&gt;__attribute__ &lt;span class="pre"&gt;((__cleanup__(int_cleanup)))&lt;/span&gt; int&lt;/tt&gt;.
But I like to keep macro expansion straightforward.&lt;/p&gt;
&lt;p&gt;Another annoying aspect of the cleanup extension is in the definition of cleanup handlers.&lt;/p&gt;
&lt;p&gt;Let's say you want to automatically close a file. You would be tempted to declare your file as:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;__attribute__&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;__cleanup__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fclose&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;FILE&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;However, &lt;tt class="docutils literal"&gt;fclose&lt;/tt&gt; does not have the correct prototype, because the cleanup
extension will pass the address of &lt;tt class="docutils literal"&gt;f&lt;/tt&gt; (a &lt;tt class="docutils literal"&gt;FILE**&lt;/tt&gt; type). To automatically
generate wrappers I use the following macro (taken from System-D codebase).&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#define DEFINE_TRIVIAL_CLEANUP_FUNC(name, type, func)                          \&lt;/span&gt;
&lt;span class="cp"&gt;    static void name(type* p)                                                  \&lt;/span&gt;
&lt;span class="cp"&gt;    {                                                                          \&lt;/span&gt;
&lt;span class="cp"&gt;        if (*p) {                                                              \&lt;/span&gt;
&lt;span class="cp"&gt;            func(*p);                                                          \&lt;/span&gt;
&lt;span class="cp"&gt;        }                                                                      \&lt;/span&gt;
&lt;span class="cp"&gt;    }                                                                          \&lt;/span&gt;
&lt;span class="cp"&gt;    struct __useless_struct_to_allow_trailing_semicolon__&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;With this macro, you can define a scoped file as follows:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;// Instanciate a trivial cleanup function for FILE* types.&lt;/span&gt;
&lt;span class="n"&gt;DEFINE_TRIVIAL_CLEANUP_FUNC&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;file_cleanup&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cm"&gt;/* Name for the wrapper generated. */&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;FILE&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="cm"&gt;/* Type passed to the destructor. */&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;fclose&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="cm"&gt;/* Destructor invoked. */&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Attribute to declare scoped files.&lt;/span&gt;
&lt;span class="cp"&gt;#define scoped_file SURVIVAL_CLEANUP(file_cleanup)&lt;/span&gt;

&lt;span class="c1"&gt;// Example scoped file:&lt;/span&gt;
&lt;span class="n"&gt;scoped_file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;FILE&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;r&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion"&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I packed the macro described in this post in a header &lt;a class="reference external" href="https://github.com/thomashk0/c-snippets/blob/main/survival/survival.h"&gt;survival.h&lt;/a&gt;.
You can see them in action in a small demo &lt;a class="reference external" href="https://github.com/thomashk0/c-snippets/blob/main/survival/test/survival_demo.c"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I would be interested to hear what are your most useful macros. Feel free to PM
me or &lt;a class="reference external" href="https://github.com/thomashk0/c-snippets/issues"&gt;open an discussion&lt;/a&gt;
on the Github repository.&lt;/p&gt;
&lt;/div&gt;
</content><category term="programming"></category><category term="c"></category><category term="programming"></category><category term="tooling"></category></entry></feed>