<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:base="https://sayansivakumaran.com/" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Sayan Sivakumaran&#39;s Blog</title>
    <link>https://sayansivakumaran.com/</link>
    <atom:link href="https://sayansivakumaran.com/rss.xml" rel="self" type="application/rss+xml" />
    <description>I like writing about the nitty gritty technical details of accessibility.</description>
    <language>en</language>
    <item>
      <title>Performance Experiments are Hard</title>
      <link>https://sayansivakumaran.com/posts/2025/10/performance-experiments-are-hard/</link>
      <description>&lt;p&gt;Running good experiments is obviously hard. This is exemplified by the numerous resources you can find online
about the reproducibility crisis in various scientific fields. Naturally, running performance experiments in computer science
is also hard, and it is too easy to misinterpret the results or to present data which hides the complete story.&lt;/p&gt;
&lt;p&gt;I found it interesting how multiple fields of computer science have papers that talk about benchmarking pitfalls in their domains,
and wanted to start compiling a list for myself. Maybe it&#39;s useful for you too.&lt;/p&gt;
&lt;h2 id=&quot;systems-programming&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2025/10/performance-experiments-are-hard/#systems-programming&quot;&gt;&lt;span&gt;Systems Programming&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://dl.acm.org/doi/10.1145/1508284.1508275&quot;&gt;Producing wrong data without doing anything wrong!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gernot-heiser.org/benchmarking-crimes.html&quot;&gt;Systems Benchmarking Crimes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ieeexplore.ieee.org/document/4636099&quot;&gt;Can Hardware Performance Counters be Trusted?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ieeexplore.ieee.org/document/6557172&quot;&gt;Nondeterminism in Hardware Performance Counters&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A note on performance counters. Depending on how paranoid you are, you should double check that the performance counters your tool advertises are actually
listed in your processor manual. For example, when using &lt;code&gt;perf list&lt;/code&gt;, the tool advertises that I can measure &lt;code&gt;l2_latency.l2_cycles_waiting_on_fills&lt;/code&gt;,
even though I couldn&#39;t find that event anywhere in my Zen3 manual. It seems like the &lt;a href=&quot;https://github.com/torvalds/linux/commit/da66658638c947cab0fb157289f03698453ff8d5&quot;&gt;PR that added support for measuring that event&lt;/a&gt;
added that event because the measured count was non-zero, even though it wasn&#39;t listed in the manual. It was submitted and approved by AMD employees,
so I might just be overly cautious, but I personally wouldn&#39;t feel comfortable using that event for any rigorous measurement (and would wonder why there wasn&#39;t
a revision to the documentation if it &lt;em&gt;is&lt;/em&gt; a valid event).&lt;/p&gt;
&lt;h2 id=&quot;java&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2025/10/performance-experiments-are-hard/#java&quot;&gt;&lt;span&gt;Java&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://dl.acm.org/doi/10.1145/1297027.1297033&quot;&gt;Statistically rigorous Java performance evaluation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.cs.purdue.edu/homes/hosking/papers/oopsla06~.pdf&quot;&gt;The DaCapo Benchmarks: Java Benchmarking Development and Analysis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dl.acm.org/doi/10.1145/3617651.3622985&quot;&gt;Don’t Trust Your Profiler: An Empirical Study on the Precision and Accuracy of Java Profilers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;networking&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2025/10/performance-experiments-are-hard/#networking&quot;&gt;&lt;span&gt;Networking&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://datatracker.ietf.org/doc/html/rfc6349&quot;&gt;RFC 6349: Framework for TCP Throughput Testing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dl.acm.org/doi/10.1145/505696.505703&quot;&gt;On the effective evaluation of TCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dl.acm.org/doi/10.1145/268437.268737&quot;&gt;Why we don&#39;t know how to simulate the Internet&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
      <pubDate>Sun, 26 Oct 2025 00:00:00 +0000</pubDate>
      <dc:creator>Sayan Sivakumaran</dc:creator>
      <guid>https://sayansivakumaran.com/posts/2025/10/performance-experiments-are-hard/</guid>
    </item>
    <item>
      <title>Observing network interface statistics with iproute2</title>
      <link>https://sayansivakumaran.com/posts/2025/10/observing-network-statistics-with-iproute2/</link>
      <description>&lt;p&gt;I am a big fan of tools that lets you observe the behavior of low level systems, as it is great for learning.
For example, &lt;a href=&quot;https://en.wikipedia.org/wiki/Hardware_performance_counter&quot;&gt;hardware performance counters&lt;/a&gt; are great for observing
processor behavior that is otherwise transparent for the developer. Similarly, the &lt;a href=&quot;https://github.com/herd/herdtools7/tree/master&quot;&gt;herdtools7 suite&lt;/a&gt; is
great for observing the behavior of your processor&#39;s memory model.&lt;/p&gt;
&lt;p&gt;I&#39;ve been running a networking book club at my workplace, and I&#39;m happy
that the the &lt;code&gt;ip -s -s link show&lt;/code&gt; command can give me similar low-level visibility into the networking stack of my machine (although in much less detail than the previous two tools). The &lt;a href=&quot;https://docs.kernel.org/networking/statistics.html&quot;&gt;kernel documentation&lt;/a&gt; describes the output of this tool in a lot of detail. The only
thing I was confused by was what the &lt;code&gt;transns&lt;/code&gt; entry in the TX errors row meant, as I couldn&#39;t find it in the documentation:&lt;/p&gt;
&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;link&lt;/span&gt; show dev wlo1&lt;br /&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;: wlo1: &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;BROADCAST,MULTICAST,UP,LOWER_UP&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; mtu &lt;span class=&quot;token number&quot;&gt;1500&lt;/span&gt; qdisc noqueue state UP mode DORMANT group default qlen &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;&lt;br /&gt;    link/ether &lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;:c2:e8:ee:f3:57 brd ff:ff:ff:ff:ff:ff&lt;br /&gt;    RX:  bytes packets errors dropped  missed   mcast&lt;br /&gt;     &lt;span class=&quot;token number&quot;&gt;478520149&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;452566&lt;/span&gt;      &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;br /&gt;    RX errors:  length    crc   frame    fifo overrun&lt;br /&gt;                     &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;br /&gt;    TX:  bytes packets errors dropped carrier collsns&lt;br /&gt;      &lt;span class=&quot;token number&quot;&gt;44078438&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;164580&lt;/span&gt;      &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;       &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;br /&gt;    TX errors: aborted   fifo  window heartbt transns&lt;br /&gt;                     &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;br /&gt;    altname wlp41s0&lt;br /&gt;    altname wlx50c2e8eef357&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Thankfully, we can go spelunking in the &lt;code&gt;iproute2&lt;/code&gt; repository to see what exactly it represents. Searching the for the string &lt;code&gt;transns&lt;/code&gt; &lt;a href=&quot;https://github.com/iproute2/iproute2/blob/1c344b988c1475dc308335afb9ce528b7af3b8d8/ip/ipaddress.c#L642&quot;&gt;finds us the code
we want&lt;/a&gt; relatively easily, but it&#39;s still not clear to me what a &lt;code&gt;carrier_change&lt;/code&gt; is, or what a &lt;code&gt;carrier&lt;/code&gt; even is in the first place. The thorough git commit message helps us a lot though:&lt;/p&gt;
&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;commit 30b557929f2aaeeee59e1bbaad7c804bcae40e7b&lt;br /&gt;Author: david decotigny &amp;lt;decot@googlers.com&amp;gt;&lt;br /&gt;Date:   Mon May 5 20:38:18 2014 -0700&lt;br /&gt;&lt;br /&gt;    iproute2: show counter of carrier on&amp;lt;-&amp;gt;off transitions&lt;br /&gt;&lt;br /&gt;    This patch allows to display the current counter of carrier on&amp;lt;-&amp;gt;off&lt;br /&gt;    transitions (IFLA_CARRIER_CHANGES, see kernel commit &amp;quot;expose number of&lt;br /&gt;    carrier on/off changes&amp;quot;):&lt;br /&gt;&lt;br /&gt;      ip -s -s link show dev eth0&lt;br /&gt;      32: eth0: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 ...&lt;br /&gt;        link/ether ................. brd ff:ff:ff:ff:ff:ff&lt;br /&gt;        RX: bytes  packets  errors  dropped overrun mcast&lt;br /&gt;        125552461  258881   0       0       0       10150&lt;br /&gt;        RX errors: length  crc     frame   fifo    missed&lt;br /&gt;                   0        0       0       0       0&lt;br /&gt;        TX: bytes  packets  errors  dropped carrier collsns&lt;br /&gt;        40426119   224444   0       0       0       0&lt;br /&gt;        TX errors: aborted fifo    window  heartbeat transns&lt;br /&gt;                   0        0       0       0        3&lt;br /&gt;&lt;br /&gt;    Tested:&lt;br /&gt;      - kernel with patch &amp;quot;net-sysfs: expose number of carrier on/off&lt;br /&gt;        changes&amp;quot;: see &amp;quot;transns&amp;quot; column above&lt;br /&gt;      - kernel wthout the patch: &amp;quot;transns&amp;quot; not displayed (as expected)&lt;br /&gt;&lt;br /&gt;    Signed-off-by: David Decotigny &amp;lt;decot@googlers.com&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sadly, I wasn&#39;t able to immediately figure out what a &lt;code&gt;carrier&lt;/code&gt; was from the &lt;a href=&quot;https://github.com/torvalds/linux/commit/2d3b479df41a10e2f41f9259fcba775bd34de6e4&quot;&gt;mentioned kernel commit&lt;/a&gt; either. Some resources online seem to imply that &lt;code&gt;carrier_changes&lt;/code&gt; count the number of times a specific interface went up or down, which seems plausible as the &lt;code&gt;transns&lt;/code&gt; number seems to go up whenever I manually toggle my computer&#39;s &lt;code&gt;wlo1&lt;/code&gt; interface on and off.&lt;/p&gt;
</description>
      <pubDate>Sun, 26 Oct 2025 00:00:00 +0000</pubDate>
      <dc:creator>Sayan Sivakumaran</dc:creator>
      <guid>https://sayansivakumaran.com/posts/2025/10/observing-network-statistics-with-iproute2/</guid>
    </item>
    <item>
      <title>A Brief Look at the Mathematics of Structure Packing</title>
      <link>https://sayansivakumaran.com/posts/2025/9/math-struct-packing/</link>
      <description>&lt;p&gt;It&#39;s common knowledge that the memory layout of a structure in C can
change depending on the order its members were declared in. For example, on my x86-64 processor,
&lt;code&gt;sizeof(Foo)&lt;/code&gt; is not equal to &lt;code&gt;sizeof(Bar)&lt;/code&gt;, even though they effectively have the
same members. &lt;a href=&quot;https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:&#39;1&#39;,fontScale:14,fontUsePx:&#39;0&#39;,j:1,lang:___c,selection:(endColumn:1,endLineNumber:14,positionColumn:1,positionLineNumber:14,selectionStartColumn:1,selectionStartLineNumber:14,startColumn:1,startLineNumber:14),source:&#39;%23include+%3Cstdio.h%3E%0A%0Astruct+Foo+%7B%0A++++char+firstChar%3B%0A++++double+firstDouble%3B%0A++++char+secondChar%3B%0A%7D%3B%0A%0Astruct+Bar+%7B%0A++++double+firstDouble%3B%0A++++char+firstChar%3B%0A++++char+secondChar%3B%0A%7D%3B%0A%0Aint+main(void)+%7B%0A++++printf(%22Size+of+Foo:+%25zu%5Cn%22,+sizeof(struct+Foo))%3B%0A++++printf(%22Size+of+Bar:+%25zu%22,+sizeof(struct+Bar))%3B%0A++++return+0%3B%0A%7D%0A&#39;),l:&#39;5&#39;,n:&#39;0&#39;,o:&#39;C+source+%231&#39;,t:&#39;0&#39;)),k:45.36247334754797,l:&#39;4&#39;,n:&#39;0&#39;,o:&#39;&#39;,s:0,t:&#39;0&#39;),(g:!((h:executor,i:(argsPanelShown:&#39;1&#39;,compilationPanelShown:&#39;0&#39;,compiler:cclang2010,compilerName:&#39;&#39;,compilerOutShown:&#39;0&#39;,execArgs:&#39;&#39;,execStdin:&#39;&#39;,fontScale:14,fontUsePx:&#39;0&#39;,j:1,lang:___c,libs:!(),options:&#39;&#39;,overrides:!(),runtimeTools:!(),source:1,stdinPanelShown:&#39;1&#39;,wrap:&#39;1&#39;),l:&#39;5&#39;,n:&#39;0&#39;,o:&#39;Executor+x86-64+clang+20.1.0+(C,+Editor+%231)&#39;,t:&#39;0&#39;)),header:(),k:26.22601279317697,l:&#39;4&#39;,n:&#39;0&#39;,o:&#39;&#39;,s:0,t:&#39;0&#39;),(g:!((h:executor,i:(argsPanelShown:&#39;1&#39;,compilationPanelShown:&#39;0&#39;,compiler:cclang2010,compilerName:&#39;&#39;,compilerOutShown:&#39;0&#39;,execArgs:&#39;&#39;,execStdin:&#39;&#39;,fontScale:14,fontUsePx:&#39;0&#39;,j:2,lang:___c,libs:!(),options:&#39;-m32&#39;,overrides:!(),runtimeTools:!(),source:1,stdinPanelShown:&#39;1&#39;,wrap:&#39;1&#39;),l:&#39;5&#39;,n:&#39;0&#39;,o:&#39;Executor+x86-64+clang+20.1.0+(C,+Editor+%231)&#39;,t:&#39;0&#39;)),header:(),k:28.411513859275054,l:&#39;4&#39;,n:&#39;0&#39;,o:&#39;&#39;,s:0,t:&#39;0&#39;)),l:&#39;2&#39;,n:&#39;0&#39;,o:&#39;&#39;,t:&#39;0&#39;)),version:4&quot;&gt;You can try it out yourself on Godbolt&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;language-c&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt; firstChar&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;double&lt;/span&gt; firstDouble&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt; secondChar&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Bar&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;double&lt;/span&gt; firstDouble&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt; firstChar&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt; secondChar&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It&#39;s also common knowledge that ordering the members of your structure from largest alignment to
smallest will &lt;em&gt;usually&lt;/em&gt; (?) give you a size minimizing layout. If this discussion is new to you, there
are lots of good articles and videos on the topic, though &lt;a href=&quot;http://www.catb.org/esr/structure-packing&quot;&gt;&amp;quot;The Lost Art of Structure Packing&amp;quot;&lt;/a&gt;
seems to be the most popular.&lt;/p&gt;
&lt;p&gt;I was curious if we could get a more precise answer on when the strategy above is or isn&#39;t optimal. More specifically, I had two questions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Does ordering structure members from largest to smallest alignment always give a size minimal
layout?&lt;/strong&gt; &lt;br /&gt;As most people know, the answer is no, and &lt;a href=&quot;https://sayansivakumaran.com/posts/2025/9/math-struct-packing/#counterexample-to-the-ordering-by-alignment-algorithm&quot;&gt;it is trivial to construct a counterexample&lt;/a&gt;. But we can describe a class of &amp;quot;simple&amp;quot; structures where the answer always is yes!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Clang&#39;s &lt;a href=&quot;https://clang.llvm.org/docs/analyzer/checkers.html#optin-performance-padding&quot;&gt;optin.performance.Padding analyzer&lt;/a&gt; uses a slightly different algorithm than what is commonly recommended to find an order that minimizes a structure&#39;s size. Does this algorithm always find a size minimal
layout?&lt;/strong&gt; &lt;br /&gt;It turns out the answer is still no! Once again, we can construct &lt;a href=&quot;https://sayansivakumaran.com/posts/2025/9/math-struct-packing/#counterexample-to-clangs-optin-performance-padding-analyzer&quot;&gt;an admittedly contrived counterexample&lt;/a&gt;
that we can optimize better by hand.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I tried to find formal mathematical answers to the problems above, but I didn&#39;t have much luck outside of
people concluding the correctness of these algorithms from trying them out on a couple of very
simple examples, giving handwavy proofs that missed edge cases, or just calling the problem trivial.&lt;/p&gt;
&lt;p&gt;It&#39;s almost certain that mathematical answers are available in literature I&#39;m unfamiliar with. But I wasn&#39;t able to find them, so my curiosity led me to
try and give answers to the problems above on my own. It was definitely a good homework problem for me, at the very least!&lt;/p&gt;
&lt;p&gt;The rest of this blog post fills in the details needed for providing an answer to the first
question above. We don&#39;t need any powerful mathematical tools here - because we add so many restrictions
on the problem, a familiarity with modular arithmetic will be enough. Of course, I haven&#39;t done any math
since my undergrad, so my skills may be rusty and the proofs may contain errors. Please let me know if you find any. 🙂&lt;/p&gt;
&lt;p&gt;&lt;table-of-contents&gt;&lt;/table-of-contents&gt;&lt;/p&gt;
&lt;h2 id=&quot;disclaimers&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2025/9/math-struct-packing/#disclaimers&quot;&gt;&lt;span&gt;Disclaimers&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This can become a complicated topic if the scope is too wide, so let&#39;s narrow the scope a bit.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;I will not analyze structures with bitfield members.&lt;/strong&gt; From a cursory reading, it seems like
the layout of bitfield members in a structure is a complicated implementation-defined topic.  I don&#39;t really have
the knowledge to reason about this in any real way across every potential target out there. So let&#39;s ignore this case for now.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Interestingly enough, &lt;a href=&quot;https://github.com/llvm/llvm-project/blob/478b4b012f6c70f799ffeb3523b5a160aed8726b/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp#L169&quot;&gt;Clang&#39;s static analyzer also considers this case to be hard&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;I will not make any claims about the &#39;performance&#39; of a size minimal layout.&lt;/strong&gt; Performance is
obviously a complicated topic, and what is &#39;performant&#39; can change depending on the metric you
are defining performance by. Even worse, designing good experiments is &lt;a href=&quot;https://dl.acm.org/doi/10.1145/1508284.1508275&quot;&gt;famously hard&lt;/a&gt;.
The hope is, however, that a size minimal layout will increase the density of data in cache,
which &lt;em&gt;might&lt;/em&gt; make your memory-bound workload faster.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Figuring out an &quot;optimally performing&quot; layout of a structure seems to be an active area of
research. You can search for the keywords &lt;a href=&quot;https://scholar.google.com/scholar?hl=en&amp;as_sdt=0%2C50&amp;q=%22structure+splitting%22+AND+%22llvm%22&amp;btnG=&quot;&gt;structure splitting&lt;/a&gt; and &lt;a href=&quot;https://scholar.google.com/scholar?start=0&amp;q=%22field+reordering%22&amp;hl=en&amp;as_sdt=0,50&quot;&gt;field reordering&lt;/a&gt; if you&#39;re
curious. The literature seems to suggest that it&#39;s often smarter to find structure layouts accounting for access patterns rather than purely minimizing size, although that does require having knowledge about what the access pattern of a program looks like.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;I will assume that we care about alignment.&lt;/strong&gt; If not, we can trivially solve the problem by
adding &lt;code&gt;__attribute__((__packed__))&lt;/code&gt; to the structure. There has been &lt;a href=&quot;https://lemire.me/blog/2012/05/31/data-alignment-for-speed-myth-or-reality/&quot;&gt;some discussion&lt;/a&gt; questioning
how important alignment is on modern processors, but to my understanding there are still platforms
that trap upon unaligned reads or writes. In any case, let&#39;s assume we want to find a size minimal layout while
respecting alignment requirements.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In case you&#39;re curious, it seems &lt;a href=&quot;https://orchistro.tistory.com/206&quot;&gt;you can make x86 trap on unaligned reads or writes&lt;/a&gt; if you
want! The mentioned flag was also present in the manual for my Ryzen 5950x processor, anyway.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;vocabulary&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2025/9/math-struct-packing/#vocabulary&quot;&gt;&lt;span&gt;Vocabulary&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We&#39;ll use:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&#92;(S&#92;) to denote some arbitrary structure with &#92;(n &#92;gt 0&#92;) members.
&lt;ul&gt;
&lt;li&gt;Again, for the sake of simplicity, let&#39;s ignore structures with bitfield members for now.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&#92;(m_i&#92;) to denote the &#92;(i&#92;)th member of the structure, with &#92;(0 &#92;lt i &#92;leq n&#92;).&lt;/li&gt;
&lt;li&gt;&#92;(s_i&#92;) to denote the &lt;code&gt;sizeof&lt;/code&gt; member &#92;(m_i&#92;).&lt;/li&gt;
&lt;li&gt;&#92;(a_i&#92;) to denote the alignment of member &#92;(m_i&#92;), where &#92;(a_i=2^{k_i}&#92;) for some integer &#92;(k_i &#92;geq 0&#92;)
&lt;ul&gt;
&lt;li&gt;My hope is that restricting &#92;(a_i&#92;) to be a power of 2 is a reasonable assumption. I don&#39;t know if
there are any exotic architectures where that doesn&#39;t apply, but if there are this blog post
does not apply to those architectures.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&#92;(a_&#92;text{max}&#92;) to denote the maximum alignment out of all &#92;(a_i&#92;) in &#92;(S&#92;). In other words, &#92;(a_&#92;text{max}&#92;) is the smallest integer such that &#92;(a_&#92;text{max} &#92;geq a_i&#92;)
for all &#92;(i&#92;).&lt;/li&gt;
&lt;li&gt;&#92;(p_i&#92;) to denote the padding between members &#92;(m_i&#92;) and &#92;(m_{i+1}&#92;) (or the trailing padding if &#92;(m_i&#92;)
is the last member of the structure)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some might be curious why we make a distinction between the size &#92;(s_i&#92;) and alignment &#92;(a_i&#92;)
of structure members, as I see people conflate the two sometimes. This is because they aren&#39;t always equal. For example, executing &lt;a href=&quot;https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:&#39;1&#39;,fontScale:14,fontUsePx:&#39;0&#39;,j:1,lang:___c,selection:(endColumn:1,endLineNumber:9,positionColumn:1,positionLineNumber:9,selectionStartColumn:1,selectionStartLineNumber:9,startColumn:1,startLineNumber:9),source:&#39;%23include+%3Cstdio.h%3E%0A%23include+%3Cstdalign.h%3E%0A%0Aint+main(void)+%7B%0A++++printf(%22Size+of+double:+%25lu%5Cn%22,+sizeof(double))%3B%0A++++printf(%22Alignment+of+double:+%25lu%22,+alignof(double))%3B%0A++++return+0%3B%0A%7D%0A&#39;),l:&#39;5&#39;,n:&#39;0&#39;,o:&#39;C+source+%231&#39;,t:&#39;0&#39;)),k:50,l:&#39;4&#39;,n:&#39;0&#39;,o:&#39;&#39;,s:0,t:&#39;0&#39;),(g:!((h:executor,i:(argsPanelShown:&#39;1&#39;,compilationPanelShown:&#39;0&#39;,compiler:cg151,compilerName:&#39;&#39;,compilerOutShown:&#39;0&#39;,execArgs:&#39;&#39;,execStdin:&#39;&#39;,fontScale:14,fontUsePx:&#39;0&#39;,j:1,lang:___c,libs:!(),options:&#39;&#39;,overrides:!(),runtimeTools:!(),source:1,stdinPanelShown:&#39;1&#39;,wrap:&#39;1&#39;),l:&#39;5&#39;,n:&#39;0&#39;,o:&#39;Executor+x86-64+gcc+15.1+(C,+Editor+%231)&#39;,t:&#39;0&#39;)),header:(),k:25,l:&#39;4&#39;,n:&#39;0&#39;,o:&#39;&#39;,s:0,t:&#39;0&#39;),(g:!((h:executor,i:(argsPanelShown:&#39;1&#39;,compilationPanelShown:&#39;0&#39;,compiler:cg151,compilerName:&#39;&#39;,compilerOutShown:&#39;0&#39;,execArgs:&#39;&#39;,execStdin:&#39;&#39;,fontScale:14,fontUsePx:&#39;0&#39;,j:2,lang:___c,libs:!(),options:&#39;-m32&#39;,overrides:!(),runtimeTools:!(),source:1,stdinPanelShown:&#39;1&#39;,wrap:&#39;1&#39;),l:&#39;5&#39;,n:&#39;0&#39;,o:&#39;Executor+x86-64+gcc+15.1+(C,+Editor+%231)&#39;,t:&#39;0&#39;)),header:(),k:25,l:&#39;4&#39;,n:&#39;0&#39;,o:&#39;&#39;,s:0,t:&#39;0&#39;)),l:&#39;2&#39;,n:&#39;0&#39;,o:&#39;&#39;,t:&#39;0&#39;)),version:4&quot;&gt;this program
on Godbolt&lt;/a&gt;
shows that when compiling for 32 bit systems with the &lt;code&gt;-m32&lt;/code&gt; flag, &lt;code&gt;gcc&lt;/code&gt; will report that
&lt;code&gt;sizeof(double)&lt;/code&gt; is 8 bytes but the &lt;code&gt;alignof(double)&lt;/code&gt; is 4 bytes.&lt;/p&gt;
&lt;h2 id=&quot;formulating-a-mathematical-definition-of-sizeof&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2025/9/math-struct-packing/#formulating-a-mathematical-definition-of-sizeof&quot;&gt;&lt;span&gt;Formulating a mathematical definition of &lt;code&gt;sizeof&lt;/code&gt;&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We can&#39;t do any mathematics here unless we know how to write &lt;code&gt;sizeof&lt;/code&gt; down as an equation.
Let&#39;s attempt to formulate one, and we&#39;ll then prove an important property of &lt;code&gt;sizeof&lt;/code&gt; that
is normally taken for granted.&lt;/p&gt;
&lt;h3 id=&quot;a-potential-ambiguity-in-the-definition-of-sizeof&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2025/9/math-struct-packing/#a-potential-ambiguity-in-the-definition-of-sizeof&quot;&gt;&lt;span&gt;A potential ambiguity in the definition of &lt;code&gt;sizeof&lt;/code&gt;&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;First off, the definition of &lt;code&gt;sizeof&lt;/code&gt; from 6.5.3.4, paragraph 4 of the &lt;a href=&quot;https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3096.pdf&quot;&gt;C23 standard (PDF)&lt;/a&gt; is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When [sizeof is] applied to an operand that has structure or union type, the result is the total number of bytes in such an object, including internal and trailing padding.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;However, unless I&#39;m grossly misunderstanding something, I think this definition ambiguous.
For example, consider the following structure &lt;code&gt;Foo&lt;/code&gt; in an x86-64 environment:&lt;/p&gt;
&lt;pre class=&quot;language-c&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;short&lt;/span&gt; a&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Takes up bytes 0 and 1 &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;   &lt;span class=&quot;token comment&quot;&gt;// Pad to a 4 byte boundary, then takes up bytes 4 through 7 &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;short&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// No padding needed. Takes up bytes 8 and 9. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;             &lt;span class=&quot;token comment&quot;&gt;// Trailing padding needed to make sure consecutive &lt;/span&gt;&lt;br /&gt;             &lt;span class=&quot;token comment&quot;&gt;// copies of Foo in an array are aligned. As the &lt;/span&gt;&lt;br /&gt;             &lt;span class=&quot;token comment&quot;&gt;// alignment of Foo is 4, add 2 final bytes of padding.&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;sizeof&lt;/code&gt; this structure should be 12 bytes. Indeed, this is how &lt;code&gt;sizeof&lt;/code&gt; is normally computed (&lt;a href=&quot;https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:&#39;1&#39;,fontScale:14,fontUsePx:&#39;0&#39;,j:1,lang:___c,selection:(endColumn:1,endLineNumber:18,positionColumn:1,positionLineNumber:18,selectionStartColumn:1,selectionStartLineNumber:18,startColumn:1,startLineNumber:18),source:&#39;%23include+%3Cstdio.h%3E%0A%0Astruct+Foo+%7B%0A++++short+a%3B+//+Takes+up+bytes+1+and+2+%0A%0A++++int+b%3B+++//+Pad+to+a+4+byte+boundary,+then+takes+up+bytes+4+through+8+%0A%0A++++short+c%3B+//+No+padding+needed.+Takes+up+bytes+9+and+10.+%0A%0A+++++++++++++//+Trailing+padding+needed+to+make+sure+consecutive+copies+of+Foo+in%0A+++++++++++++//+an+array+are+aligned.+Add+2+final+bytes+of+padding.%0A%7D%3B%0A%0Aint+main(void)+%7B%0A++++printf(%22Sizeof+Foo:+%25zu%22,+sizeof(struct+Foo))%3B%0A++++return+0%3B%0A%7D%0A&#39;),l:&#39;5&#39;,n:&#39;0&#39;,o:&#39;C+source+%231&#39;,t:&#39;0&#39;)),k:50,l:&#39;4&#39;,n:&#39;0&#39;,o:&#39;&#39;,s:0,t:&#39;0&#39;),(g:!((h:executor,i:(argsPanelShown:&#39;1&#39;,compilationPanelShown:&#39;0&#39;,compiler:cg151,compilerName:&#39;&#39;,compilerOutShown:&#39;0&#39;,execArgs:&#39;&#39;,execStdin:&#39;&#39;,fontScale:14,fontUsePx:&#39;0&#39;,j:1,lang:___c,libs:!(),options:&#39;&#39;,overrides:!(),runtimeTools:!(),source:1,stdinPanelShown:&#39;1&#39;,wrap:&#39;1&#39;),l:&#39;5&#39;,n:&#39;0&#39;,o:&#39;Executor+x86-64+gcc+15.1+(C,+Editor+%231)&#39;,t:&#39;0&#39;)),header:(),k:50,l:&#39;4&#39;,n:&#39;0&#39;,o:&#39;&#39;,s:0,t:&#39;0&#39;)),l:&#39;2&#39;,n:&#39;0&#39;,o:&#39;&#39;,t:&#39;0&#39;)),version:4&quot;&gt;try it out on Godbolt&lt;/a&gt;),
and this computation is correct as long as the structure &lt;code&gt;Foo&lt;/code&gt; is aligned on the largest alignment
of its members, which happens to be &#92;(a_&#92;text{max}=4&#92;).&lt;/p&gt;
&lt;p&gt;Here is another way to state this. Let &#92;(M&#92;) be the memory address that &lt;code&gt;Foo&lt;/code&gt; starts at. Then this computation is correct as long
as:&lt;/p&gt;
&lt;p&gt;$$M &#92;equiv 0&#92;pmod{4}$$&lt;/p&gt;
&lt;p&gt;and we could visualize the &lt;code&gt;sizeof&lt;/code&gt; computation above as follows (hope you can forgive the sloppy Inkscape):&lt;/p&gt;

&lt;svg class=&quot;overflow-max-content-width&quot; width=&quot;651.87&quot; height=&quot;108.09&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 172.47 28.6&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot;&gt;
&lt;title&gt;A visualization of the size computation described in the comments for the Foo struct above. Two instances of Foo are laid side by side, with the first instance of Foo starting at memory address 0.&lt;/title&gt;
&lt;g transform=&quot;translate(-8.3978 -9.0627)&quot;&gt;
&lt;rect x=&quot;23.371&quot; y=&quot;15.084&quot; width=&quot;6.9089&quot; height=&quot;6.9089&quot; fill-opacity=&quot;0&quot; stroke=&quot;#000&quot; stroke-width=&quot;.39688&quot;&gt;&lt;/rect&gt;
&lt;rect x=&quot;30.422&quot; y=&quot;15.084&quot; width=&quot;6.9089&quot; height=&quot;6.9089&quot; fill-opacity=&quot;0&quot; stroke=&quot;#000&quot; stroke-width=&quot;.39688&quot;&gt;&lt;/rect&gt;
&lt;rect x=&quot;79.808&quot; y=&quot;15.084&quot; width=&quot;6.9089&quot; height=&quot;6.9089&quot; fill-opacity=&quot;0&quot; stroke=&quot;#000&quot; stroke-width=&quot;.39688&quot;&gt;&lt;/rect&gt;
&lt;rect x=&quot;86.859&quot; y=&quot;15.084&quot; width=&quot;6.9089&quot; height=&quot;6.9089&quot; fill-opacity=&quot;0&quot; stroke=&quot;#000&quot; stroke-width=&quot;.39688&quot;&gt;&lt;/rect&gt;
&lt;rect x=&quot;164.66&quot; y=&quot;15.084&quot; width=&quot;6.9089&quot; height=&quot;6.9089&quot; fill-opacity=&quot;0&quot; stroke=&quot;#000&quot; stroke-width=&quot;.39688&quot;&gt;&lt;/rect&gt;
&lt;rect x=&quot;171.71&quot; y=&quot;15.084&quot; width=&quot;6.9089&quot; height=&quot;6.9089&quot; fill-opacity=&quot;0&quot; stroke=&quot;#000&quot; stroke-width=&quot;.39688&quot;&gt;&lt;/rect&gt;
&lt;rect x=&quot;108.01&quot; y=&quot;15.084&quot; width=&quot;6.9089&quot; height=&quot;6.9089&quot; fill-opacity=&quot;0&quot; stroke=&quot;#000&quot; stroke-width=&quot;.39688&quot;&gt;&lt;/rect&gt;
&lt;rect x=&quot;115.06&quot; y=&quot;15.084&quot; width=&quot;6.9089&quot; height=&quot;6.9089&quot; fill-opacity=&quot;0&quot; stroke=&quot;#000&quot; stroke-width=&quot;.39688&quot;&gt;&lt;/rect&gt;
&lt;g transform=&quot;translate(0 .59009)&quot; stroke=&quot;#000&quot; stroke-width=&quot;.39688&quot;&gt;
&lt;rect x=&quot;9.2701&quot; y=&quot;14.494&quot; width=&quot;6.9089&quot; height=&quot;6.9089&quot; fill=&quot;#a7baff&quot;&gt;&lt;/rect&gt;
&lt;g fill=&quot;#a7cfff&quot;&gt;
&lt;path d=&quot;m10.591 18.95 3.02-3.02z&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m11.796 19.93 3.02-3.02z&quot;&gt;&lt;/path&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;g transform=&quot;translate(7.0506 .59009)&quot; stroke=&quot;#000&quot; stroke-width=&quot;.39688&quot;&gt;
&lt;rect x=&quot;9.2701&quot; y=&quot;14.494&quot; width=&quot;6.9089&quot; height=&quot;6.9089&quot; fill=&quot;#a7baff&quot;&gt;&lt;/rect&gt;
&lt;g fill=&quot;#a7cfff&quot;&gt;
&lt;path d=&quot;m10.591 18.95 3.02-3.02z&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m11.796 19.93 3.02-3.02z&quot;&gt;&lt;/path&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;g transform=&quot;translate(3.7492 .30671)&quot;&gt;
&lt;g id=&quot;f&quot; transform=&quot;translate(-.12765 .24731)&quot;&gt;
&lt;rect transform=&quot;translate(-8.3512 .03607)&quot; x=&quot;42.202&quot; y=&quot;14.494&quot; width=&quot;6.9089&quot; height=&quot;6.9089&quot; fill=&quot;#8eeb78&quot; stroke=&quot;#000&quot; stroke-width=&quot;.39688&quot;&gt;&lt;/rect&gt;
&lt;path d=&quot;m38.269 20.03-3.02-3.02z&quot; fill=&quot;#a7cfff&quot; stroke=&quot;#000&quot; stroke-width=&quot;.39688&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m39.249 18.825-3.02-3.02z&quot; fill=&quot;#a7cfff&quot; stroke=&quot;#000&quot; stroke-width=&quot;.39688&quot;&gt;&lt;/path&gt;
&lt;/g&gt;
&lt;use id=&quot;d&quot; transform=&quot;translate(7.0613)&quot; xlink:href=&quot;#f&quot;&gt;&lt;/use&gt;
&lt;use id=&quot;b&quot; transform=&quot;translate(6.9538)&quot; xlink:href=&quot;#d&quot;&gt;&lt;/use&gt;
&lt;use transform=&quot;translate(7.1689)&quot; xlink:href=&quot;#b&quot;&gt;&lt;/use&gt;
&lt;/g&gt;
&lt;g transform=&quot;translate(88.388 .30671)&quot;&gt;
&lt;g id=&quot;e&quot; transform=&quot;translate(-.12765 .24731)&quot;&gt;
&lt;rect transform=&quot;translate(-8.3512 .03607)&quot; x=&quot;42.202&quot; y=&quot;14.494&quot; width=&quot;6.9089&quot; height=&quot;6.9089&quot; fill=&quot;#8eeb78&quot; stroke=&quot;#000&quot; stroke-width=&quot;.39688&quot;&gt;&lt;/rect&gt;
&lt;path d=&quot;m38.269 20.03-3.02-3.02z&quot; fill=&quot;#a7cfff&quot; stroke=&quot;#000&quot; stroke-width=&quot;.39688&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m39.249 18.825-3.02-3.02z&quot; fill=&quot;#a7cfff&quot; stroke=&quot;#000&quot; stroke-width=&quot;.39688&quot;&gt;&lt;/path&gt;
&lt;/g&gt;
&lt;use id=&quot;c&quot; transform=&quot;translate(7.0613)&quot; xlink:href=&quot;#e&quot;&gt;&lt;/use&gt;
&lt;use id=&quot;a&quot; transform=&quot;translate(7.1689)&quot; xlink:href=&quot;#c&quot;&gt;&lt;/use&gt;
&lt;use transform=&quot;translate(7.1689)&quot; xlink:href=&quot;#a&quot;&gt;&lt;/use&gt;
&lt;/g&gt;
&lt;g transform=&quot;translate(56.437 .59009)&quot; stroke=&quot;#000&quot; stroke-width=&quot;.39688&quot;&gt;
&lt;rect x=&quot;9.2701&quot; y=&quot;14.494&quot; width=&quot;6.9089&quot; height=&quot;6.9089&quot; fill=&quot;#a7baff&quot;&gt;&lt;/rect&gt;
&lt;g fill=&quot;#a7cfff&quot;&gt;
&lt;path d=&quot;m10.591 18.95 3.02-3.02z&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m11.796 19.93 3.02-3.02z&quot;&gt;&lt;/path&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;g transform=&quot;translate(63.487 .59009)&quot; stroke=&quot;#000&quot; stroke-width=&quot;.39688&quot;&gt;
&lt;rect x=&quot;9.2701&quot; y=&quot;14.494&quot; width=&quot;6.9089&quot; height=&quot;6.9089&quot; fill=&quot;#a7baff&quot;&gt;&lt;/rect&gt;
&lt;g fill=&quot;#a7cfff&quot;&gt;
&lt;path d=&quot;m10.591 18.95 3.02-3.02z&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m11.796 19.93 3.02-3.02z&quot;&gt;&lt;/path&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;g transform=&quot;translate(84.639 .59009)&quot; stroke=&quot;#000&quot; stroke-width=&quot;.39688&quot;&gt;
&lt;rect x=&quot;9.2701&quot; y=&quot;14.494&quot; width=&quot;6.9089&quot; height=&quot;6.9089&quot; fill=&quot;#a7baff&quot;&gt;&lt;/rect&gt;
&lt;g fill=&quot;#a7cfff&quot;&gt;
&lt;path d=&quot;m10.591 18.95 3.02-3.02z&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m11.796 19.93 3.02-3.02z&quot;&gt;&lt;/path&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;g transform=&quot;translate(91.69 .59009)&quot; stroke=&quot;#000&quot; stroke-width=&quot;.39688&quot;&gt;
&lt;rect x=&quot;9.2701&quot; y=&quot;14.494&quot; width=&quot;6.9089&quot; height=&quot;6.9089&quot; fill=&quot;#a7baff&quot;&gt;&lt;/rect&gt;
&lt;g fill=&quot;#a7cfff&quot;&gt;
&lt;path d=&quot;m10.591 18.95 3.02-3.02z&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m11.796 19.93 3.02-3.02z&quot;&gt;&lt;/path&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;g transform=&quot;translate(141.29 .59009)&quot; stroke=&quot;#000&quot; stroke-width=&quot;.39688&quot;&gt;
&lt;rect x=&quot;9.2701&quot; y=&quot;14.494&quot; width=&quot;6.9089&quot; height=&quot;6.9089&quot; fill=&quot;#a7baff&quot;&gt;&lt;/rect&gt;
&lt;g fill=&quot;#a7cfff&quot;&gt;
&lt;path d=&quot;m10.591 18.95 3.02-3.02z&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m11.796 19.93 3.02-3.02z&quot;&gt;&lt;/path&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;g transform=&quot;translate(148.34 .59009)&quot; stroke=&quot;#000&quot; stroke-width=&quot;.39688&quot;&gt;
&lt;rect x=&quot;9.2701&quot; y=&quot;14.494&quot; width=&quot;6.9089&quot; height=&quot;6.9089&quot; fill=&quot;#a7baff&quot;&gt;&lt;/rect&gt;
&lt;g fill=&quot;#a7cfff&quot;&gt;
&lt;path d=&quot;m10.591 18.95 3.02-3.02z&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m11.796 19.93 3.02-3.02z&quot;&gt;&lt;/path&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;text x=&quot;15.222&quot; y=&quot;11.559965&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; xml:space=&quot;preserve&quot;&gt;&lt;tspan x=&quot;15.222&quot; y=&quot;11.559965&quot; fill=&quot;#000000&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;1&lt;/tspan&gt;&lt;/text&gt;
&lt;text x=&quot;8.3176947&quot; y=&quot;11.555314&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; xml:space=&quot;preserve&quot;&gt;&lt;tspan x=&quot;8.3176947&quot; y=&quot;11.555314&quot; fill=&quot;#000000&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;0&lt;/tspan&gt;&lt;/text&gt;
&lt;text x=&quot;11.340604&quot; y=&quot;28.241587&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; xml:space=&quot;preserve&quot;&gt;&lt;tspan x=&quot;11.340604&quot; y=&quot;28.241587&quot; fill=&quot;#000000&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.21&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;short&lt;/tspan&gt;&lt;/text&gt;
&lt;text x=&quot;68.246185&quot; y=&quot;28.241587&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; xml:space=&quot;preserve&quot;&gt;&lt;tspan x=&quot;68.246185&quot; y=&quot;28.241587&quot; fill=&quot;#000000&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.21&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;short&lt;/tspan&gt;&lt;/text&gt;
&lt;text x=&quot;48.238914&quot; y=&quot;28.262516&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; xml:space=&quot;preserve&quot;&gt;&lt;tspan x=&quot;48.238914&quot; y=&quot;28.262516&quot; fill=&quot;#000000&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.21&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;int&lt;/tspan&gt;&lt;/text&gt;
&lt;text x=&quot;42.280159&quot; y=&quot;37.496346&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; xml:space=&quot;preserve&quot;&gt;&lt;tspan x=&quot;42.280159&quot; y=&quot;37.496346&quot; fill=&quot;#000000&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.21&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;struct Foo&lt;/tspan&gt;&lt;/text&gt;
&lt;text x=&quot;22.291641&quot; y=&quot;11.580119&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; xml:space=&quot;preserve&quot;&gt;&lt;tspan x=&quot;22.291641&quot; y=&quot;11.580119&quot; fill=&quot;#000000&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;2&lt;/tspan&gt;&lt;/text&gt;
&lt;text x=&quot;29.263273&quot; y=&quot;11.556089&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; xml:space=&quot;preserve&quot;&gt;&lt;tspan x=&quot;29.263273&quot; y=&quot;11.556089&quot; fill=&quot;#000000&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;3&lt;/tspan&gt;&lt;/text&gt;
&lt;text x=&quot;36.409653&quot; y=&quot;11.556089&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; xml:space=&quot;preserve&quot;&gt;&lt;tspan x=&quot;36.409653&quot; y=&quot;11.556089&quot; fill=&quot;#000000&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;4&lt;/tspan&gt;&lt;/text&gt;
&lt;text x=&quot;43.452736&quot; y=&quot;11.53206&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; xml:space=&quot;preserve&quot;&gt;&lt;tspan x=&quot;43.452736&quot; y=&quot;11.53206&quot; fill=&quot;#000000&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;5&lt;/tspan&gt;&lt;/text&gt;
&lt;text x=&quot;50.433151&quot; y=&quot;11.553764&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; xml:space=&quot;preserve&quot;&gt;&lt;tspan x=&quot;50.433151&quot; y=&quot;11.553764&quot; fill=&quot;#000000&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;6&lt;/tspan&gt;&lt;/text&gt;
&lt;text x=&quot;57.467388&quot; y=&quot;11.556089&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; xml:space=&quot;preserve&quot;&gt;&lt;tspan x=&quot;57.467388&quot; y=&quot;11.556089&quot; fill=&quot;#000000&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;7&lt;/tspan&gt;&lt;/text&gt;
&lt;text x=&quot;64.604927&quot; y=&quot;11.556089&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; xml:space=&quot;preserve&quot;&gt;&lt;tspan x=&quot;64.604927&quot; y=&quot;11.556089&quot; fill=&quot;#000000&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;8&lt;/tspan&gt;&lt;/text&gt;
&lt;text x=&quot;71.554825&quot; y=&quot;11.556865&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; xml:space=&quot;preserve&quot;&gt;&lt;tspan x=&quot;71.554825&quot; y=&quot;11.556865&quot; fill=&quot;#000000&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;9&lt;/tspan&gt;&lt;/text&gt;
&lt;text x=&quot;77.629433&quot; y=&quot;11.555314&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; xml:space=&quot;preserve&quot;&gt;&lt;tspan x=&quot;77.629433&quot; y=&quot;11.555314&quot; fill=&quot;#000000&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;10&lt;/tspan&gt;&lt;/text&gt;
&lt;text x=&quot;84.741508&quot; y=&quot;11.559965&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; xml:space=&quot;preserve&quot;&gt;&lt;tspan x=&quot;84.741508&quot; y=&quot;11.559965&quot; fill=&quot;#000000&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;11&lt;/tspan&gt;&lt;/text&gt;
&lt;text x=&quot;91.743675&quot; y=&quot;11.580119&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; xml:space=&quot;preserve&quot;&gt;&lt;tspan x=&quot;91.743675&quot; y=&quot;11.580119&quot; fill=&quot;#000000&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;12&lt;/tspan&gt;&lt;/text&gt;
&lt;text x=&quot;98.674446&quot; y=&quot;11.556089&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; xml:space=&quot;preserve&quot;&gt;&lt;tspan x=&quot;98.674446&quot; y=&quot;11.556089&quot; fill=&quot;#000000&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;13&lt;/tspan&gt;&lt;/text&gt;
&lt;text x=&quot;105.32887&quot; y=&quot;11.559965&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; xml:space=&quot;preserve&quot;&gt;&lt;tspan x=&quot;105.32887&quot; y=&quot;11.559965&quot; fill=&quot;#000000&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;14&lt;/tspan&gt;&lt;/text&gt;
&lt;text x=&quot;112.64304&quot; y=&quot;11.535935&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; xml:space=&quot;preserve&quot;&gt;&lt;tspan x=&quot;112.64304&quot; y=&quot;11.535935&quot; fill=&quot;#000000&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;15&lt;/tspan&gt;&lt;/text&gt;
&lt;text x=&quot;120.0452&quot; y=&quot;11.553764&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; xml:space=&quot;preserve&quot;&gt;&lt;tspan x=&quot;120.0452&quot; y=&quot;11.553764&quot; fill=&quot;#000000&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;16&lt;/tspan&gt;&lt;/text&gt;
&lt;text x=&quot;127.15488&quot; y=&quot;11.559965&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; xml:space=&quot;preserve&quot;&gt;&lt;tspan x=&quot;127.15488&quot; y=&quot;11.559965&quot; fill=&quot;#000000&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;17&lt;/tspan&gt;&lt;/text&gt;
&lt;g transform=&quot;translate(.3358 -1.3786)&quot;&gt;
&lt;text x=&quot;133.75627&quot; y=&quot;12.934712&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; xml:space=&quot;preserve&quot;&gt;&lt;tspan x=&quot;133.75627&quot; y=&quot;12.934712&quot; fill=&quot;#000000&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;18&lt;/tspan&gt;&lt;/text&gt;
&lt;/g&gt;
&lt;g transform=&quot;translate(7.437 -1.3778)&quot;&gt;
&lt;text x=&quot;133.75627&quot; y=&quot;12.934712&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; xml:space=&quot;preserve&quot;&gt;&lt;tspan x=&quot;133.75627&quot; y=&quot;12.934712&quot; fill=&quot;#000000&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;19&lt;/tspan&gt;&lt;/text&gt;
&lt;/g&gt;
&lt;g transform=&quot;translate(14.722 -1.3786)&quot;&gt;
&lt;text x=&quot;133.75627&quot; y=&quot;12.934712&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; xml:space=&quot;preserve&quot;&gt;&lt;tspan x=&quot;133.75627&quot; y=&quot;12.934712&quot; fill=&quot;#000000&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;20&lt;/tspan&gt;&lt;/text&gt;
&lt;/g&gt;
&lt;g transform=&quot;translate(21.758 -1.3546)&quot;&gt;
&lt;text x=&quot;133.75627&quot; y=&quot;12.934712&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; xml:space=&quot;preserve&quot;&gt;&lt;tspan x=&quot;133.75627&quot; y=&quot;12.934712&quot; fill=&quot;#000000&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;21&lt;/tspan&gt;&lt;/text&gt;
&lt;/g&gt;
&lt;g transform=&quot;translate(28.835 -1.3546)&quot;&gt;
&lt;text x=&quot;133.75627&quot; y=&quot;12.934712&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; xml:space=&quot;preserve&quot;&gt;&lt;tspan x=&quot;133.75627&quot; y=&quot;12.934712&quot; fill=&quot;#000000&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;22&lt;/tspan&gt;&lt;/text&gt;
&lt;/g&gt;
&lt;g transform=&quot;translate(35.963 -1.3786)&quot;&gt;
&lt;text x=&quot;133.75627&quot; y=&quot;12.934712&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; xml:space=&quot;preserve&quot;&gt;&lt;tspan x=&quot;133.75627&quot; y=&quot;12.934712&quot; fill=&quot;#000000&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;23&lt;/tspan&gt;&lt;/text&gt;
&lt;/g&gt;
&lt;g transform=&quot;translate(43.099 -1.3546)&quot;&gt;
&lt;text x=&quot;133.75627&quot; y=&quot;12.934712&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; xml:space=&quot;preserve&quot;&gt;&lt;tspan x=&quot;133.75627&quot; y=&quot;12.934712&quot; fill=&quot;#000000&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;24&lt;/tspan&gt;&lt;/text&gt;
&lt;/g&gt;
&lt;path d=&quot;m9.2566 15.213v-2.5498&quot; fill=&quot;none&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.37&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m16.26 15.213v-2.5498&quot; fill=&quot;none&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.37&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m23.296 15.213v-2.5498&quot; fill=&quot;none&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.37&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m30.369 15.213v-2.5498&quot; fill=&quot;none&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.37&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m37.441 15.213v-2.5498&quot; fill=&quot;none&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.37&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m44.478 15.213v-2.5498&quot; fill=&quot;none&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.37&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m51.49 15.213v-2.5498&quot; fill=&quot;none&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.37&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m58.509 15.213v-2.5498&quot; fill=&quot;none&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.37&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m65.631 15.213v-2.5498&quot; fill=&quot;none&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.37&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m72.674 15.213v-2.5498&quot; fill=&quot;none&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.37&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m79.759 15.213v-2.5498&quot; fill=&quot;none&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.37&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m86.785 15.213v-2.5498&quot; fill=&quot;none&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.37&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m93.875 15.213v-2.5498&quot; fill=&quot;none&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.37&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m100.89 15.213v-2.5498&quot; fill=&quot;none&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.37&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m107.95 15.213v-2.5498&quot; fill=&quot;none&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.37&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m114.98 15.213v-2.5498&quot; fill=&quot;none&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.37&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m122.04 15.213v-2.5498&quot; fill=&quot;none&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.37&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m129.1 15.213v-2.5498&quot; fill=&quot;none&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.37&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m136.21 15.213v-2.5498&quot; fill=&quot;none&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.37&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m150.49 15.213v-2.5498&quot; fill=&quot;none&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.37&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m157.51 15.213v-2.5498&quot; fill=&quot;none&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.37&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m164.63 15.213v-2.5498&quot; fill=&quot;none&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.37&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m171.7 15.213v-2.5498&quot; fill=&quot;none&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.37&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m178.62 15.213v-2.5498&quot; fill=&quot;none&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.37&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m143.39 15.213v-2.5498&quot; fill=&quot;none&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.37&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m9.3282 22.7v2.2484h13.49v-2.2484&quot; fill=&quot;none&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.37&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m66.115 22.7v2.2484h13.49v-2.2484&quot; fill=&quot;none&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.37&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m37.48 22.753v2.1431h27.285v-2.1431&quot; fill=&quot;none&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.37&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;m9.3441 27.759v5.2626h84.129v-5.2626&quot; fill=&quot;none&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.40261&quot;&gt;&lt;/path&gt;
&lt;text x=&quot;127.25977&quot; y=&quot;37.515381&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; xml:space=&quot;preserve&quot;&gt;&lt;tspan x=&quot;127.25977&quot; y=&quot;37.515381&quot; fill=&quot;#000000&quot; font-family=&quot;Monospace&quot; font-size=&quot;3.175px&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.21&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;struct Foo&lt;/tspan&gt;&lt;/text&gt;
&lt;path d=&quot;m94.324 27.778v5.2626h84.129v-5.2626&quot; fill=&quot;none&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;1.1&quot; stroke-width=&quot;.40261&quot;&gt;&lt;/path&gt;
&lt;/g&gt;
&lt;/svg&gt;
&lt;p&gt;If you&#39;re confused why we need to add 2 bytes of trailing padding, suppose that we have an array of
&lt;code&gt;Foo&lt;/code&gt;. Without the trailing padding in the example above, the &lt;code&gt;int&lt;/code&gt; in the second instance of &lt;code&gt;Foo&lt;/code&gt;
would be misaligned.&lt;/p&gt;
&lt;p&gt;However, suppose that we hypothetically had a memory allocator that could allocate a memory address &#92;(M&#92;) such that&lt;/p&gt;
&lt;p&gt;$$M &#92;equiv 2&#92;pmod{4}$$&lt;/p&gt;
&lt;p&gt;That is, it could allocate memory such that the address it returns would have a remainder of 2 when
divided by 4. Then, if we start &lt;code&gt;Foo&lt;/code&gt; at that memory address, it would have a size of 8 bytes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The first member &lt;code&gt;short a&lt;/code&gt; would already be aligned, and would take up bytes 2 and 3.&lt;/li&gt;
&lt;li&gt;The second member &lt;code&gt;int b&lt;/code&gt; would already be aligned because it would start at a memory address divisible by 4,
and would take up bytes 4 through 7.&lt;/li&gt;
&lt;li&gt;The third member &lt;code&gt;short c&lt;/code&gt; would already be aligned, and would take up bytes 8 and 9.&lt;/li&gt;
&lt;li&gt;There is no trailing padding needed, since in an array the first instance of &lt;code&gt;Foo&lt;/code&gt; would end on a
memory address that has remainder 2 when divided by 4, so we can immediately start the next
instance of &lt;code&gt;Foo&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We could visualize this computation as follows:&lt;/p&gt;
&lt;p&gt;&lt;svg class=&quot;overflow-max-content-width&quot; height=&quot;109.538&quot; id=&quot;svg1&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 172.47293 28.98193&quot; width=&quot;651.86621&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot;&gt;&lt;title&gt;A visualization of the size computation described above, where Foo happens to start an unusual alignment. Two instances of Foo are laid side by side, with the first instance of Foo starting at memory address 2.&lt;/title&gt;&lt;defs id=&quot;defs1&quot;&gt;&lt;/defs&gt;&lt;g id=&quot;layer1&quot; transform=&quot;translate(-8.3977933,-9.0627017)&quot;&gt;&lt;rect height=&quot;6.9088931&quot; id=&quot;rect11&quot; style=&quot;fill:#000;fill-opacity:0;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot; width=&quot;6.9088931&quot; x=&quot;9.2700644&quot; y=&quot;15.083898&quot;&gt;&lt;/rect&gt;&lt;rect height=&quot;6.9088931&quot; id=&quot;rect12&quot; style=&quot;fill:#000;fill-opacity:0;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot; width=&quot;6.9088931&quot; x=&quot;16.320635&quot; y=&quot;15.083898&quot;&gt;&lt;/rect&gt;&lt;rect height=&quot;6.9088931&quot; id=&quot;rect20&quot; style=&quot;fill:#000;fill-opacity:0;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot; width=&quot;6.9088931&quot; x=&quot;150.56114&quot; y=&quot;15.083898&quot;&gt;&lt;/rect&gt;&lt;rect height=&quot;6.9088931&quot; id=&quot;rect21&quot; style=&quot;fill:#000;fill-opacity:0;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot; width=&quot;6.9088931&quot; x=&quot;157.61171&quot; y=&quot;15.083898&quot;&gt;&lt;/rect&gt;&lt;rect height=&quot;6.9088931&quot; id=&quot;rect20-5&quot; style=&quot;fill:#000;fill-opacity:0;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot; width=&quot;6.9088931&quot; x=&quot;164.66228&quot; y=&quot;15.083898&quot;&gt;&lt;/rect&gt;&lt;rect height=&quot;6.9088931&quot; id=&quot;rect21-4&quot; style=&quot;fill:#000;fill-opacity:0;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot; width=&quot;6.9088931&quot; x=&quot;171.71284&quot; y=&quot;15.083898&quot;&gt;&lt;/rect&gt;&lt;rect height=&quot;6.9088931&quot; id=&quot;rect24&quot; style=&quot;fill:#000;fill-opacity:0;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot; width=&quot;6.9088931&quot; x=&quot;136.34167&quot; y=&quot;15.083898&quot;&gt;&lt;/rect&gt;&lt;rect height=&quot;6.9088931&quot; id=&quot;rect25&quot; style=&quot;fill:#000;fill-opacity:0;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot; width=&quot;6.9088931&quot; x=&quot;143.51056&quot; y=&quot;15.083898&quot;&gt;&lt;/rect&gt;&lt;g id=&quot;g31&quot; transform=&quot;translate(14.10114,0.59008598)&quot;&gt;&lt;rect height=&quot;6.9088931&quot; id=&quot;rect2&quot; style=&quot;fill:#a7baff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot; width=&quot;6.9088931&quot; x=&quot;9.2700644&quot; y=&quot;14.493812&quot;&gt;&lt;/rect&gt;&lt;g id=&quot;g30&quot;&gt;&lt;path d=&quot;m 10.590962,18.949624 3.020002,-3.020003 z&quot; id=&quot;path30&quot; style=&quot;fill:#a7cfff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m 11.796081,19.929795 3.020002,-3.020003 z&quot; id=&quot;path30-5&quot; style=&quot;fill:#a7cfff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;g id=&quot;g31-7&quot; transform=&quot;translate(21.151711,0.59008598)&quot;&gt;&lt;rect height=&quot;6.9088931&quot; id=&quot;rect2-18&quot; style=&quot;fill:#a7baff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot; width=&quot;6.9088931&quot; x=&quot;9.2700644&quot; y=&quot;14.493812&quot;&gt;&lt;/rect&gt;&lt;g id=&quot;g30-9&quot;&gt;&lt;path d=&quot;m 10.590962,18.949624 3.020002,-3.020003 z&quot; id=&quot;path30-3&quot; style=&quot;fill:#a7cfff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m 11.796081,19.929795 3.020002,-3.020003 z&quot; id=&quot;path30-5-7&quot; style=&quot;fill:#a7cfff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;g id=&quot;g31-9&quot; transform=&quot;translate(3.7492449,0.30670542)&quot;&gt;&lt;g id=&quot;g32&quot; transform=&quot;translate(-0.12764846,0.2473103)&quot;&gt;&lt;rect height=&quot;6.9088931&quot; id=&quot;rect14&quot; style=&quot;fill:#8eeb78;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot; width=&quot;6.9088931&quot; x=&quot;42.201988&quot; y=&quot;14.493812&quot; transform=&quot;translate(-8.3512386,0.03607008)&quot;&gt;&lt;/rect&gt;&lt;path d=&quot;M 38.268886,20.030413 35.248883,17.010411 Z&quot; id=&quot;path30-3-8&quot; style=&quot;fill:#a7cfff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M 39.249057,18.825294 36.229055,15.805292 Z&quot; id=&quot;path30-5-9-9&quot; style=&quot;fill:#a7cfff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;use id=&quot;use33&quot; transform=&quot;translate(7.0613242)&quot; x=&quot;0&quot; xlink:href=&quot;#g32&quot; y=&quot;0&quot;&gt;&lt;/use&gt;&lt;use id=&quot;use34&quot; transform=&quot;translate(6.9537549)&quot; x=&quot;0&quot; xlink:href=&quot;#use33&quot; y=&quot;0&quot;&gt;&lt;/use&gt;&lt;use id=&quot;use35&quot; transform=&quot;translate(7.1688935)&quot; x=&quot;0&quot; xlink:href=&quot;#use34&quot; y=&quot;0&quot;&gt;&lt;/use&gt;&lt;/g&gt;&lt;g id=&quot;g32-2&quot; transform=&quot;translate(60.058422,0.5540159)&quot;&gt;&lt;rect height=&quot;6.9088931&quot; id=&quot;rect14-8&quot; style=&quot;fill:#8eeb78;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot; width=&quot;6.9088931&quot; x=&quot;42.201988&quot; y=&quot;14.493812&quot; transform=&quot;translate(-8.3512386,0.03607008)&quot;&gt;&lt;/rect&gt;&lt;path d=&quot;M 38.268886,20.030413 35.248883,17.010411 Z&quot; id=&quot;path30-3-8-4&quot; style=&quot;fill:#a7cfff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M 39.249057,18.825294 36.229055,15.805292 Z&quot; id=&quot;path30-5-9-9-0&quot; style=&quot;fill:#a7cfff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g id=&quot;g31-2&quot; transform=&quot;translate(56.436825,0.5900858)&quot;&gt;&lt;rect height=&quot;6.9088931&quot; id=&quot;rect2-6&quot; style=&quot;fill:#a7baff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot; width=&quot;6.9088931&quot; x=&quot;9.2700644&quot; y=&quot;14.493812&quot;&gt;&lt;/rect&gt;&lt;g id=&quot;g30-8&quot;&gt;&lt;path d=&quot;m 10.590962,18.949624 3.020002,-3.020003 z&quot; id=&quot;path30-9&quot; style=&quot;fill:#a7cfff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m 11.796081,19.929795 3.020002,-3.020003 z&quot; id=&quot;path30-5-1&quot; style=&quot;fill:#a7cfff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;g id=&quot;g31-93&quot; transform=&quot;translate(63.487395,0.5900858)&quot;&gt;&lt;rect height=&quot;6.9088931&quot; id=&quot;rect2-1&quot; style=&quot;fill:#a7baff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot; width=&quot;6.9088931&quot; x=&quot;9.2700644&quot; y=&quot;14.493812&quot;&gt;&lt;/rect&gt;&lt;g id=&quot;g30-1&quot;&gt;&lt;path d=&quot;m 10.590962,18.949624 3.020002,-3.020003 z&quot; id=&quot;path30-4&quot; style=&quot;fill:#a7cfff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m 11.796081,19.929795 3.020002,-3.020003 z&quot; id=&quot;path30-5-95&quot; style=&quot;fill:#a7cfff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;g id=&quot;g31-0&quot; transform=&quot;translate(70.537965,0.59008598)&quot;&gt;&lt;rect height=&quot;6.9088931&quot; id=&quot;rect2-75&quot; style=&quot;fill:#a7baff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot; width=&quot;6.9088931&quot; x=&quot;9.2700644&quot; y=&quot;14.493812&quot;&gt;&lt;/rect&gt;&lt;g id=&quot;g30-7&quot;&gt;&lt;path d=&quot;m 10.590962,18.949624 3.020002,-3.020003 z&quot; id=&quot;path30-50&quot; style=&quot;fill:#a7cfff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m 11.796081,19.929795 3.020002,-3.020003 z&quot; id=&quot;path30-5-6&quot; style=&quot;fill:#a7cfff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;g id=&quot;g31-06&quot; transform=&quot;translate(77.588532,0.59008598)&quot;&gt;&lt;rect height=&quot;6.9088931&quot; id=&quot;rect2-2&quot; style=&quot;fill:#a7baff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot; width=&quot;6.9088931&quot; x=&quot;9.2700644&quot; y=&quot;14.493812&quot;&gt;&lt;/rect&gt;&lt;g id=&quot;g30-4&quot;&gt;&lt;path d=&quot;m 10.590962,18.949624 3.020002,-3.020003 z&quot; id=&quot;path30-7&quot; style=&quot;fill:#a7cfff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m 11.796081,19.929795 3.020002,-3.020003 z&quot; id=&quot;path30-5-4&quot; style=&quot;fill:#a7cfff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;g id=&quot;g31-0-1&quot; transform=&quot;translate(112.84139,0.59008598)&quot;&gt;&lt;rect height=&quot;6.9088931&quot; id=&quot;rect2-75-3&quot; style=&quot;fill:#a7baff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot; width=&quot;6.9088931&quot; x=&quot;9.2700644&quot; y=&quot;14.493812&quot;&gt;&lt;/rect&gt;&lt;g id=&quot;g30-7-6&quot;&gt;&lt;path d=&quot;m 10.590962,18.949624 3.020002,-3.020003 z&quot; id=&quot;path30-50-9&quot; style=&quot;fill:#a7cfff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m 11.796081,19.929795 3.020002,-3.020003 z&quot; id=&quot;path30-5-6-0&quot; style=&quot;fill:#a7cfff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;g id=&quot;g31-06-4&quot; transform=&quot;translate(119.90271,0.59008598)&quot;&gt;&lt;rect height=&quot;6.9088931&quot; id=&quot;rect2-2-0&quot; style=&quot;fill:#a7baff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot; width=&quot;6.9088931&quot; x=&quot;9.2700644&quot; y=&quot;14.493812&quot;&gt;&lt;/rect&gt;&lt;g id=&quot;g30-4-2&quot;&gt;&lt;path d=&quot;m 10.590962,18.949624 3.020002,-3.020003 z&quot; id=&quot;path30-7-4&quot; style=&quot;fill:#a7cfff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m 11.796081,19.929795 3.020002,-3.020003 z&quot; id=&quot;path30-5-4-4&quot; style=&quot;fill:#a7cfff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;text id=&quot;text37&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000;fill-opacity:1;stroke:#000;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; x=&quot;15.222&quot; xml:space=&quot;preserve&quot; y=&quot;11.559965&quot;&gt;&lt;tspan id=&quot;tspan37&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000;fill-opacity:1;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0&quot; x=&quot;15.222&quot; y=&quot;11.559965&quot;&gt;1&lt;/tspan&gt;&lt;/text&gt;&lt;text id=&quot;text37-6&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000;fill-opacity:1;stroke:#000;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; x=&quot;8.3176947&quot; xml:space=&quot;preserve&quot; y=&quot;11.555314&quot;&gt;&lt;tspan id=&quot;tspan37-0&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000;fill-opacity:1;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0&quot; x=&quot;8.3176947&quot; y=&quot;11.555314&quot;&gt;0&lt;/tspan&gt;&lt;/text&gt;&lt;text id=&quot;text37-6-1&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000;fill-opacity:1;stroke:#000;stroke-width:.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; x=&quot;25.628101&quot; xml:space=&quot;preserve&quot; y=&quot;28.241587&quot;&gt;&lt;tspan id=&quot;tspan37-0-8&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000;fill-opacity:1;stroke-width:.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0&quot; x=&quot;25.628101&quot; y=&quot;28.241587&quot;&gt;short&lt;/tspan&gt;&lt;/text&gt;&lt;text id=&quot;text37-6-1-3&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000;fill-opacity:1;stroke:#000;stroke-width:.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; x=&quot;68.246185&quot; xml:space=&quot;preserve&quot; y=&quot;28.241587&quot;&gt;&lt;tspan id=&quot;tspan37-0-8-7&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000;fill-opacity:1;stroke-width:.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0&quot; x=&quot;68.246185&quot; y=&quot;28.241587&quot;&gt;short&lt;/tspan&gt;&lt;/text&gt;&lt;text id=&quot;text37-6-1-7&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000;fill-opacity:1;stroke:#000;stroke-width:.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; x=&quot;48.238914&quot; xml:space=&quot;preserve&quot; y=&quot;28.262516&quot;&gt;&lt;tspan id=&quot;tspan37-0-8-2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000;fill-opacity:1;stroke-width:.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0&quot; x=&quot;48.238914&quot; y=&quot;28.262516&quot;&gt;int&lt;/tspan&gt;&lt;/text&gt;&lt;text id=&quot;text37-6-1-7-3&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000;fill-opacity:1;stroke:#000;stroke-width:.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; x=&quot;41.611115&quot; xml:space=&quot;preserve&quot; y=&quot;37.897774&quot;&gt;&lt;tspan id=&quot;tspan37-0-8-2-7&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000;fill-opacity:1;stroke-width:.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0&quot; x=&quot;41.611115&quot; y=&quot;37.897774&quot;&gt;struct Foo&lt;/tspan&gt;&lt;/text&gt;&lt;text id=&quot;text38&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000;fill-opacity:1;stroke:#000;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; x=&quot;22.291641&quot; xml:space=&quot;preserve&quot; y=&quot;11.580119&quot;&gt;&lt;tspan id=&quot;tspan38&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000;fill-opacity:1;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0&quot; x=&quot;22.291641&quot; y=&quot;11.580119&quot;&gt;2&lt;/tspan&gt;&lt;/text&gt;&lt;text id=&quot;text39&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000;fill-opacity:1;stroke:#000;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; x=&quot;29.263273&quot; xml:space=&quot;preserve&quot; y=&quot;11.556089&quot;&gt;&lt;tspan id=&quot;tspan39&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000;fill-opacity:1;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0&quot; x=&quot;29.263273&quot; y=&quot;11.556089&quot;&gt;3&lt;/tspan&gt;&lt;/text&gt;&lt;text id=&quot;text40&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000;fill-opacity:1;stroke:#000;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; x=&quot;36.409653&quot; xml:space=&quot;preserve&quot; y=&quot;11.556089&quot;&gt;&lt;tspan id=&quot;tspan40&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000;fill-opacity:1;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0&quot; x=&quot;36.409653&quot; y=&quot;11.556089&quot;&gt;4&lt;/tspan&gt;&lt;/text&gt;&lt;text id=&quot;text41&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000;fill-opacity:1;stroke:#000;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; x=&quot;43.452736&quot; xml:space=&quot;preserve&quot; y=&quot;11.53206&quot;&gt;&lt;tspan id=&quot;tspan41&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000;fill-opacity:1;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0&quot; x=&quot;43.452736&quot; y=&quot;11.53206&quot;&gt;5&lt;/tspan&gt;&lt;/text&gt;&lt;text id=&quot;text42&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000;fill-opacity:1;stroke:#000;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; x=&quot;50.433151&quot; xml:space=&quot;preserve&quot; y=&quot;11.553764&quot;&gt;&lt;tspan id=&quot;tspan42&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000;fill-opacity:1;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0&quot; x=&quot;50.433151&quot; y=&quot;11.553764&quot;&gt;6&lt;/tspan&gt;&lt;/text&gt;&lt;text id=&quot;text43&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000;fill-opacity:1;stroke:#000;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; x=&quot;57.467388&quot; xml:space=&quot;preserve&quot; y=&quot;11.556089&quot;&gt;&lt;tspan id=&quot;tspan43&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000;fill-opacity:1;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0&quot; x=&quot;57.467388&quot; y=&quot;11.556089&quot;&gt;7&lt;/tspan&gt;&lt;/text&gt;&lt;text id=&quot;text44&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000;fill-opacity:1;stroke:#000;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; x=&quot;64.604927&quot; xml:space=&quot;preserve&quot; y=&quot;11.556089&quot;&gt;&lt;tspan id=&quot;tspan44&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000;fill-opacity:1;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0&quot; x=&quot;64.604927&quot; y=&quot;11.556089&quot;&gt;8&lt;/tspan&gt;&lt;/text&gt;&lt;text id=&quot;text45&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000;fill-opacity:1;stroke:#000;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; x=&quot;71.554825&quot; xml:space=&quot;preserve&quot; y=&quot;11.556865&quot;&gt;&lt;tspan id=&quot;tspan45&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000;fill-opacity:1;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0&quot; x=&quot;71.554825&quot; y=&quot;11.556865&quot;&gt;9&lt;/tspan&gt;&lt;/text&gt;&lt;text id=&quot;text46&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000;fill-opacity:1;stroke:#000;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; x=&quot;77.629433&quot; xml:space=&quot;preserve&quot; y=&quot;11.555314&quot;&gt;&lt;tspan id=&quot;tspan46&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000;fill-opacity:1;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0&quot; x=&quot;77.629433&quot; y=&quot;11.555314&quot;&gt;10&lt;/tspan&gt;&lt;/text&gt;&lt;text id=&quot;text47&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000;fill-opacity:1;stroke:#000;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; x=&quot;84.741508&quot; xml:space=&quot;preserve&quot; y=&quot;11.559965&quot;&gt;&lt;tspan id=&quot;tspan47&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000;fill-opacity:1;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0&quot; x=&quot;84.741508&quot; y=&quot;11.559965&quot;&gt;11&lt;/tspan&gt;&lt;/text&gt;&lt;text id=&quot;text48&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000;fill-opacity:1;stroke:#000;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; x=&quot;91.743675&quot; xml:space=&quot;preserve&quot; y=&quot;11.580119&quot;&gt;&lt;tspan id=&quot;tspan48&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000;fill-opacity:1;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0&quot; x=&quot;91.743675&quot; y=&quot;11.580119&quot;&gt;12&lt;/tspan&gt;&lt;/text&gt;&lt;text id=&quot;text49&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000;fill-opacity:1;stroke:#000;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; x=&quot;98.674446&quot; xml:space=&quot;preserve&quot; y=&quot;11.556089&quot;&gt;&lt;tspan id=&quot;tspan49&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000;fill-opacity:1;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0&quot; x=&quot;98.674446&quot; y=&quot;11.556089&quot;&gt;13&lt;/tspan&gt;&lt;/text&gt;&lt;text id=&quot;text50&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000;fill-opacity:1;stroke:#000;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; x=&quot;105.32887&quot; xml:space=&quot;preserve&quot; y=&quot;11.559965&quot;&gt;&lt;tspan id=&quot;tspan50&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000;fill-opacity:1;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0&quot; x=&quot;105.32887&quot; y=&quot;11.559965&quot;&gt;14&lt;/tspan&gt;&lt;/text&gt;&lt;text id=&quot;text51&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000;fill-opacity:1;stroke:#000;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; x=&quot;112.64304&quot; xml:space=&quot;preserve&quot; y=&quot;11.535935&quot;&gt;&lt;tspan id=&quot;tspan51&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000;fill-opacity:1;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0&quot; x=&quot;112.64304&quot; y=&quot;11.535935&quot;&gt;15&lt;/tspan&gt;&lt;/text&gt;&lt;text id=&quot;text52&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000;fill-opacity:1;stroke:#000;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; x=&quot;120.0452&quot; xml:space=&quot;preserve&quot; y=&quot;11.553764&quot;&gt;&lt;tspan id=&quot;tspan52&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000;fill-opacity:1;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0&quot; x=&quot;120.0452&quot; y=&quot;11.553764&quot;&gt;16&lt;/tspan&gt;&lt;/text&gt;&lt;text id=&quot;text52-0&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000;fill-opacity:1;stroke:#000;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; x=&quot;127.15488&quot; xml:space=&quot;preserve&quot; y=&quot;11.559965&quot;&gt;&lt;tspan id=&quot;tspan52-3&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000;fill-opacity:1;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0&quot; x=&quot;127.15488&quot; y=&quot;11.559965&quot;&gt;17&lt;/tspan&gt;&lt;/text&gt;&lt;g id=&quot;g1&quot; transform=&quot;translate(0.33580204,-1.3786228)&quot;&gt;&lt;text id=&quot;text52-1&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000;fill-opacity:1;stroke:#000;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; x=&quot;133.75627&quot; xml:space=&quot;preserve&quot; y=&quot;12.934712&quot;&gt;&lt;tspan id=&quot;tspan52-5&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000;fill-opacity:1;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0&quot; x=&quot;133.75627&quot; y=&quot;12.934712&quot;&gt;18&lt;/tspan&gt;&lt;/text&gt;&lt;/g&gt;&lt;g id=&quot;g1-1&quot; transform=&quot;translate(7.4369862,-1.3778477)&quot;&gt;&lt;text id=&quot;text52-3&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000;fill-opacity:1;stroke:#000;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; x=&quot;133.75627&quot; xml:space=&quot;preserve&quot; y=&quot;12.934712&quot;&gt;&lt;tspan id=&quot;tspan52-6&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000;fill-opacity:1;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0&quot; x=&quot;133.75627&quot; y=&quot;12.934712&quot;&gt;19&lt;/tspan&gt;&lt;/text&gt;&lt;/g&gt;&lt;g id=&quot;g1-1-2&quot; transform=&quot;translate(14.722155,-1.3786228)&quot;&gt;&lt;text id=&quot;text52-3-5&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000;fill-opacity:1;stroke:#000;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; x=&quot;133.75627&quot; xml:space=&quot;preserve&quot; y=&quot;12.934712&quot;&gt;&lt;tspan id=&quot;tspan52-6-6&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000;fill-opacity:1;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0&quot; x=&quot;133.75627&quot; y=&quot;12.934712&quot;&gt;20&lt;/tspan&gt;&lt;/text&gt;&lt;/g&gt;&lt;g id=&quot;g1-1-0&quot; transform=&quot;translate(21.757547,-1.3545933)&quot;&gt;&lt;text id=&quot;text52-3-8&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000;fill-opacity:1;stroke:#000;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; x=&quot;133.75627&quot; xml:space=&quot;preserve&quot; y=&quot;12.934712&quot;&gt;&lt;tspan id=&quot;tspan52-6-2&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000;fill-opacity:1;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0&quot; x=&quot;133.75627&quot; y=&quot;12.934712&quot;&gt;21&lt;/tspan&gt;&lt;/text&gt;&lt;/g&gt;&lt;g id=&quot;g1-1-23&quot; transform=&quot;translate(28.834679,-1.3545933)&quot;&gt;&lt;text id=&quot;text52-3-3&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000;fill-opacity:1;stroke:#000;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; x=&quot;133.75627&quot; xml:space=&quot;preserve&quot; y=&quot;12.934712&quot;&gt;&lt;tspan id=&quot;tspan52-6-21&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000;fill-opacity:1;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0&quot; x=&quot;133.75627&quot; y=&quot;12.934712&quot;&gt;22&lt;/tspan&gt;&lt;/text&gt;&lt;/g&gt;&lt;g id=&quot;g1-1-9&quot; transform=&quot;translate(35.962831,-1.3786228)&quot;&gt;&lt;text id=&quot;text52-3-1&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000;fill-opacity:1;stroke:#000;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; x=&quot;133.75627&quot; xml:space=&quot;preserve&quot; y=&quot;12.934712&quot;&gt;&lt;tspan id=&quot;tspan52-6-7&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000;fill-opacity:1;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0&quot; x=&quot;133.75627&quot; y=&quot;12.934712&quot;&gt;23&lt;/tspan&gt;&lt;/text&gt;&lt;/g&gt;&lt;g id=&quot;g1-1-4&quot; transform=&quot;translate(43.098674,-1.3545933)&quot;&gt;&lt;text id=&quot;text52-3-4&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000;fill-opacity:1;stroke:#000;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; x=&quot;133.75627&quot; xml:space=&quot;preserve&quot; y=&quot;12.934712&quot;&gt;&lt;tspan id=&quot;tspan52-6-4&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000;fill-opacity:1;stroke-width:.2;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0&quot; x=&quot;133.75627&quot; y=&quot;12.934712&quot;&gt;24&lt;/tspan&gt;&lt;/text&gt;&lt;/g&gt;&lt;path d=&quot;M 9.2566274,15.212792 V 12.662959&quot; id=&quot;path57&quot; style=&quot;fill:none;fill-opacity:1;stroke:#000;stroke-width:.370001;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M 16.259683,15.212792 V 12.662959&quot; id=&quot;path57-1&quot; style=&quot;fill:none;fill-opacity:1;stroke:#000;stroke-width:.370001;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M 23.296144,15.212792 V 12.662959&quot; id=&quot;path57-8&quot; style=&quot;fill:none;fill-opacity:1;stroke:#000;stroke-width:.370001;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M 30.369017,15.212792 V 12.662959&quot; id=&quot;path57-5&quot; style=&quot;fill:none;fill-opacity:1;stroke:#000;stroke-width:.370001;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M 37.440534,15.212791 V 12.662959&quot; id=&quot;path57-12&quot; style=&quot;fill:none;fill-opacity:1;stroke:#000;stroke-width:.370001;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M 44.477827,15.212791 V 12.662959&quot; id=&quot;path57-0&quot; style=&quot;fill:none;fill-opacity:1;stroke:#000;stroke-width:.370001;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M 51.489506,15.212792 V 12.662959&quot; id=&quot;path57-2&quot; style=&quot;fill:none;fill-opacity:1;stroke:#000;stroke-width:.370001;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M 58.508901,15.212791 V 12.662959&quot; id=&quot;path57-9&quot; style=&quot;fill:none;fill-opacity:1;stroke:#000;stroke-width:.370001;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M 65.631301,15.212791 V 12.662959&quot; id=&quot;path57-97&quot; style=&quot;fill:none;fill-opacity:1;stroke:#000;stroke-width:.370001;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M 72.673941,15.212792 V 12.662959&quot; id=&quot;path57-57&quot; style=&quot;fill:none;fill-opacity:1;stroke:#000;stroke-width:.370001;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M 79.758843,15.212792 V 12.662959&quot; id=&quot;path57-05&quot; style=&quot;fill:none;fill-opacity:1;stroke:#000;stroke-width:.370001;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M 86.784573,15.212792 V 12.662959&quot; id=&quot;path57-3&quot; style=&quot;fill:none;fill-opacity:1;stroke:#000;stroke-width:.370001;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M 93.874913,15.212791 V 12.662959&quot; id=&quot;path57-11&quot; style=&quot;fill:none;fill-opacity:1;stroke:#000;stroke-width:.370001;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M 100.88909,15.212792 V 12.662959&quot; id=&quot;path57-112&quot; style=&quot;fill:none;fill-opacity:1;stroke:#000;stroke-width:.370001;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M 107.9463,15.212792 V 12.662959&quot; id=&quot;path57-32&quot; style=&quot;fill:none;fill-opacity:1;stroke:#000;stroke-width:.370001;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M 114.98049,15.212792 V 12.662959&quot; id=&quot;path57-80&quot; style=&quot;fill:none;fill-opacity:1;stroke:#000;stroke-width:.370001;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M 122.03687,15.212792 V 12.662959&quot; id=&quot;path57-23&quot; style=&quot;fill:none;fill-opacity:1;stroke:#000;stroke-width:.370001;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M 129.10394,15.212792 V 12.66296&quot; id=&quot;path57-110&quot; style=&quot;fill:none;fill-opacity:1;stroke:#000;stroke-width:.370001;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M 136.21312,15.212792 V 12.662959&quot; id=&quot;path57-52&quot; style=&quot;fill:none;fill-opacity:1;stroke:#000;stroke-width:.370001;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M 150.49273,15.212792 V 12.662959&quot; id=&quot;path57-30&quot; style=&quot;fill:none;fill-opacity:1;stroke:#000;stroke-width:.370001;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M 157.50986,15.212792 V 12.662959&quot; id=&quot;path57-27&quot; style=&quot;fill:none;fill-opacity:1;stroke:#000;stroke-width:.370001;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M 164.63316,15.212792 V 12.662959&quot; id=&quot;path57-01&quot; style=&quot;fill:none;fill-opacity:1;stroke:#000;stroke-width:.370001;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M 171.69665,15.212791 V 12.662959&quot; id=&quot;path57-02&quot; style=&quot;fill:none;fill-opacity:1;stroke:#000;stroke-width:.370001;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M 178.62339,15.212791 V 12.662959&quot; id=&quot;path57-301&quot; style=&quot;fill:none;fill-opacity:1;stroke:#000;stroke-width:.370001;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M 143.39363,15.212792 V 12.662959&quot; id=&quot;path57-4&quot; style=&quot;fill:none;fill-opacity:1;stroke:#000;stroke-width:.370001;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M 23.615657,22.700141 V 24.94852 H 37.105935 V 22.700141&quot; id=&quot;path58&quot; style=&quot;fill:none;fill-opacity:1;stroke:#000;stroke-width:.370001;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M 66.115473,22.700141 V 24.94852 H 79.605751 V 22.700141&quot; id=&quot;path58-7&quot; style=&quot;fill:none;fill-opacity:1;stroke:#000;stroke-width:.370001;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m 38.146425,22.75106 v 2.146273 H 64.768422 V 22.75106&quot; id=&quot;path58-4&quot; style=&quot;fill:none;fill-opacity:1;stroke:#000;stroke-width:.37;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m 23.214727,27.732366 v 5.313702 h 56.521594 v -5.313702&quot; id=&quot;path58-4-1&quot; style=&quot;fill:none;fill-opacity:1;stroke:#000;stroke-width:.37;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;text id=&quot;text37-6-1-7-3-7&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000;fill-opacity:1;stroke:#000;stroke-width:.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot; x=&quot;97.554192&quot; xml:space=&quot;preserve&quot; y=&quot;37.113953&quot;&gt;&lt;tspan id=&quot;tspan37-0-8-2-7-4&quot; style=&quot;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:3.175px;font-family:Monospace;-inkscape-font-specification:&#39;Monospace, Normal&#39;;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000;fill-opacity:1;stroke-width:.21;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0&quot; x=&quot;97.554192&quot; y=&quot;37.113953&quot;&gt;struct Foo&lt;/tspan&gt;&lt;/text&gt;&lt;path d=&quot;m 80.519127,27.750247 v 5.315837 h 55.452633 v -5.315837&quot; id=&quot;path58-4-1-5&quot; style=&quot;fill:none;fill-opacity:1;stroke:#000;stroke-width:.37;stroke-miterlimit:1.1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;g id=&quot;use64&quot; transform=&quot;translate(67.10899,0.55401593)&quot;&gt;&lt;rect height=&quot;6.9088931&quot; id=&quot;rect64&quot; style=&quot;fill:#8eeb78;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot; width=&quot;6.9088931&quot; x=&quot;42.201988&quot; y=&quot;14.493812&quot; transform=&quot;translate(-8.3512386,0.03607008)&quot;&gt;&lt;/rect&gt;&lt;path d=&quot;M 38.268886,20.030413 35.248883,17.010411 Z&quot; id=&quot;path64&quot; style=&quot;fill:#a7cfff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M 39.249057,18.825294 36.229055,15.805292 Z&quot; id=&quot;path65&quot; style=&quot;fill:#a7cfff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g id=&quot;use67&quot; transform=&quot;translate(74.159558,0.55401593)&quot;&gt;&lt;rect height=&quot;6.9088931&quot; id=&quot;rect69&quot; style=&quot;fill:#8eeb78;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot; width=&quot;6.9088931&quot; x=&quot;42.201988&quot; y=&quot;14.493812&quot; transform=&quot;translate(-8.3512386,0.03607008)&quot;&gt;&lt;/rect&gt;&lt;path d=&quot;M 38.268886,20.030413 35.248883,17.010411 Z&quot; id=&quot;path70&quot; style=&quot;fill:#a7cfff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M 39.249057,18.825294 36.229055,15.805292 Z&quot; id=&quot;path71&quot; style=&quot;fill:#a7cfff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g id=&quot;use71&quot; transform=&quot;translate(81.210133,0.55401593)&quot;&gt;&lt;rect height=&quot;6.9088931&quot; id=&quot;rect71&quot; style=&quot;fill:#8eeb78;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot; width=&quot;6.9088931&quot; x=&quot;42.201988&quot; y=&quot;14.493812&quot; transform=&quot;translate(-8.3512386,0.03607008)&quot;&gt;&lt;/rect&gt;&lt;path d=&quot;M 38.268886,20.030413 35.248883,17.010411 Z&quot; id=&quot;path72&quot; style=&quot;fill:#a7cfff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M 39.249057,18.825294 36.229055,15.805292 Z&quot; id=&quot;path73&quot; style=&quot;fill:#a7cfff;fill-opacity:1;stroke:#000;stroke-width:.396875;stroke-dasharray:none;stroke-opacity:1&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/p&gt;
&lt;p&gt;As far as I can see, there is nothing mathematically wrong with this scenario besides requiring a hypothetical
memory allocator that is flexible enough to support allocations like this.&lt;/p&gt;
&lt;p&gt;Indeed, I was curious why it was required for a structure to have an alignment equal to the largest
alignment of its members.
I failed to find anything in the standard about this, and most online resources I could find claimed
that it was to allow successive members in an array of structures to be aligned.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/46009715/is-the-alignof-of-a-struct-always-the-maximum-alignof-of-its-constituents&quot;&gt;(StackOverflow) Is the &lt;code&gt;alignof&lt;/code&gt; of a struct always the maximum &lt;code&gt;alignof&lt;/code&gt; of its constituents?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/10309089/why-does-size-of-the-struct-need-to-be-a-multiple-of-the-largest-alignment-of-an&quot;&gt;(StackOverflow) Why does size of the struct need to be a multiple of the largest alignment of any struct member?&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Yes, I know C and C++ are very different. I think this discussion is still relevant to C though,
and ultimately I&#39;m hoping that our discussion here is abstract enough to be language agnostic.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.quora.com/In-C-why-must-the-size-of-a-struct-be-divisible-by-the-size-of-its-largest-member&quot;&gt;(Quora) In C, why must the size of a struct be divisible by the size of its largest member?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, note that in this constructed example we have a structure that is not aligned by the
largest alignment of its members, and it still allows sensible array layouts that guarantee that
all structure members are aligned.&lt;/p&gt;
&lt;p&gt;Of course, it probably isn&#39;t useful to create a memory allocator that is flexible enough to support the
allocations above. The struct &lt;code&gt;Foo&lt;/code&gt; has an ordering of its members that ensures that &lt;code&gt;sizeof(struct Foo) = 8&lt;/code&gt; even when &#92;(M &#92;equiv 0 &#92;pmod{4}&#92;):&lt;/p&gt;
&lt;pre class=&quot;language-c&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Ordering the members of Foo from largest alignment&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// to smallest will give it the smallest size possible.&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;short&lt;/span&gt; a&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;short&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Furthermore, being able to use this trick for structures like &lt;code&gt;Foo&lt;/code&gt; doesn&#39;t necessarily mean it would work for other
structures. It is likely we can construct structures where we can show mathematically that the only &amp;quot;valid&amp;quot; alignment
of that structure is at &#92;(a_&#92;text{max}&#92;). Not to mention that this would be an ABI break if other programs aren&#39;t
using the same trick for &lt;code&gt;Foo&lt;/code&gt; that this hypothetical program is.&lt;/p&gt;
&lt;p&gt;However, the point of this example is to show that it isn&#39;t immediately obvious that &lt;code&gt;sizeof&lt;/code&gt;
will give the same value no matter what memory address we place an arbitrary structure at, even if we
restrict placing the structure at memory addresses that result in usable array layouts. The example structure &lt;code&gt;Foo&lt;/code&gt;
can start at memory addresses &#92;(M &#92;equiv 0 &#92;pmod{4}&#92;) and  &#92;(M &#92;equiv 2 &#92;pmod{4}&#92;) and we would have no issues
with inconsistent member offsets and alignments when in an array, although the value of &lt;code&gt;sizeof(struct Foo)&lt;/code&gt; would differ in both cases.&lt;/p&gt;
&lt;p&gt;From this, I claim that &lt;code&gt;sizeof&lt;/code&gt; is, in reality, a function of two arguments when applied to structures:&lt;/p&gt;
&lt;p&gt;$$
&#92;text{sizeof}(S,M)
$$&lt;/p&gt;
&lt;p&gt;where the first argument &#92;(S&#92;) is the structure in question, and the second argument &#92;(M&#92;) is the memory address the structure starts at.
We&#39;ll resolve this strange inconsistency later, and we&#39;ll prove that:&lt;/p&gt;
&lt;p&gt;$$&#92;text{sizeof}(S,0) = &#92;text{sizeof}(S,M)$$&lt;/p&gt;
&lt;p&gt;if the memory address &#92;(M&#92;) is divisible by the largest alignment &#92;(a_&#92;text{max}&#92;) in the structure &#92;(S&#92;).
In other words, we will mathematically prove what we usually take for granted: as long as a
structure is aligned in a particular way, &lt;code&gt;sizeof&lt;/code&gt; is a unary operator and we can compute &lt;code&gt;sizeof&lt;/code&gt;
pretending that the structure starts at memory address 0.&lt;/p&gt;
&lt;aside&gt;
&lt;p&gt;
We&#39;ll actually prove something slightly stronger - that the offsets of structure members are consistent as 
long as the structure starts at a memory address divisible by the structure&#39;s largest alignment. 
&lt;/p&gt;
&lt;p&gt;
As the above example shows, the offsets can change depending on the memory address a structure
starts at as well! It would certainly be unusable if the size of structures were consistent, but the
offsets inside the structures changed at different memory addresses.
&lt;/p&gt;
&lt;/aside&gt;
&lt;h3 id=&quot;the-equation-for-dsizeof&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2025/9/math-struct-packing/#the-equation-for-dsizeof&quot;&gt;&lt;span&gt;The equation for &lt;code&gt;dsizeof&lt;/code&gt;&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Before we tackle the problem of &lt;code&gt;sizeof&lt;/code&gt;, I would like to inspect a simpler concept that will
hopefully make the proof of the consistency of &lt;code&gt;sizeof&lt;/code&gt; easier to digest.&lt;/p&gt;
&lt;p&gt;We&#39;re going to &lt;a href=&quot;https://clang.llvm.org/docs/LanguageExtensions.html#datasizeof&quot;&gt;steal a concept from LLVM&lt;/a&gt;
known as &lt;code&gt;__datasizeof&lt;/code&gt;, which is defined to be the &lt;code&gt;sizeof&lt;/code&gt; a structure but without the tail padding.
We&#39;ll examine the properties of &lt;code&gt;__datasizeof&lt;/code&gt; first to reduce edge cases needed in our analysis of
&lt;code&gt;sizeof&lt;/code&gt;, and we&#39;ll denote this function mathematically as &#92;(&#92;text{dsizeof}&#92;).&lt;/p&gt;
&lt;p&gt;Similar to &lt;code&gt;sizeof&lt;/code&gt;, it turns out that &#92;(&#92;text{dsizeof}&#92;) is a function of two arguments:&lt;/p&gt;
&lt;p&gt;$$
&#92;text{dsizeof}(S,M)
$$&lt;/p&gt;
&lt;p&gt;where, once again, the first argument &#92;(S&#92;) is the structure in question, and the second argument &#92;(M&#92;) is the memory address the structure starts at.&lt;/p&gt;
&lt;p&gt;To compute an example, let&#39;s examine our structure &lt;code&gt;Foo&lt;/code&gt; again, and determine what
&#92;(&#92;text{dsizeof}(&#92;text{Foo}, 0)&#92;) ends up being:&lt;/p&gt;
&lt;pre class=&quot;language-c&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;short&lt;/span&gt; a&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Takes up bytes 0 and 1 &lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;   &lt;span class=&quot;token comment&quot;&gt;// Pad to a 4 byte boundary, then takes up bytes 4 through 7 &lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;short&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// No padding needed. Takes up bytes 8 and 9. &lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is basically the same computation as before, except we don&#39;t add the 2 bytes of trail padding,
so we end up getting:&lt;/p&gt;
&lt;p&gt;$$&#92;text{dsizeof}(&#92;text{Foo}, 0) = 10$$&lt;/p&gt;
&lt;p&gt;Similarly, if we want to compute &#92;(&#92;text{dsizeof}(&#92;text{Foo}, 2)&#92;), we can recall from the
previous section that:&lt;/p&gt;
&lt;pre class=&quot;language-c&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;short&lt;/span&gt; a&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Takes up bytes 2 and 3 &lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;   &lt;span class=&quot;token comment&quot;&gt;// No padding needed. Takes up bytes 4 through 7 &lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;short&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// No padding needed. Takes up bytes 8 and 9. &lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and so we compute:&lt;/p&gt;
&lt;p&gt;$$
&#92;text{dsizeof}(&#92;text{Foo}, 2) = 8
$$&lt;/p&gt;
&lt;p&gt;Armed with some examples, let&#39;s come up with a general equation for &#92;(&#92;text{dsizeof}&#92;).
Let &#92;(M&#92;) be the memory address that a structure &#92;(S&#92;) starts at. Then we can compute
&#92;(&#92;text{dsizeof}(S,M)&#92;) as follows:&lt;/p&gt;
&lt;p&gt;$$
&#92;text{dsizeof}(S, M) = s_1 + p_1 + s_2 + p_2 + &#92;ldots + s_{n-1} + p_{n-1} + s_n
$$&lt;/p&gt;
&lt;p&gt;All this is really saying is that the &lt;code&gt;dsizeof&lt;/code&gt; some structure is the sum of the
structure member sizes and the needed padding between those members.&lt;/p&gt;
&lt;p&gt;However, for &#92;(0 &#92;lt i &#92;lt n&#92;), we know that &#92;(p_i&#92;) cannot be some arbitrary integer - it must satisfy two constraints.
First, the choice of &#92;(p_i&#92;) must make it so the memory address of &#92;(m_{i+1}&#92;) is divisible by &#92;(a_{i+1}&#92;).
In other words, the padding must be chosen to make sure the memory address of the structure&#39;s next member respects that member&#39;s alignment.&lt;/p&gt;
&lt;p&gt;If we notice that the expression &#92;(M + s_1 + p_1 + &#92;ldots + s_i + p_i&#92;) represents the starting memory address of member
&#92;(m_{i+1}&#92;), we can encode this requirement recursively as:&lt;/p&gt;
&lt;p&gt;$$
M + s_1 + p_1 + &#92;ldots + s_i + p_i &#92;equiv 0 &#92;pmod{a_{i+1}}
$$&lt;/p&gt;
&lt;p&gt;Second, we must ensure that &#92;(p_i&#92;) is the smallest positive solution to the above equation.
This is because if we have some integer solution to the above equation &#92;(p_i=k&#92;), then &#92;(p_i=k+ca_{i+1}&#92;) is also a solution for any arbitrary
integer &#92;(c&#92;). So we add the final restriction on the value of each &#92;(p_i&#92;):&lt;/p&gt;
&lt;p&gt;$$
0 &#92;leq p_i &#92;lt a_{i+1}
$$&lt;/p&gt;
&lt;p&gt;which guarantees the uniqueness of &#92;(p_i&#92;).&lt;/p&gt;
&lt;h3 id=&quot;proving-the-consistency-of-dsizeof&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2025/9/math-struct-packing/#proving-the-consistency-of-dsizeof&quot;&gt;&lt;span&gt;Proving the consistency of &lt;code&gt;dsizeof&lt;/code&gt;&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;As an intermediary step to proving the consistency of &lt;code&gt;sizeof&lt;/code&gt;, we would like the prove the
following lemma:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lemma 1:&lt;/strong&gt; Let &#92;(M&#92;) be any memory address evenly divisible by &#92;(a_&#92;text{max}&#92;), the largest alignment in &#92;(S&#92;).
Then we have that:
$$
&#92;text{dsizeof}(S,0) = &#92;text{dsizeof}(S,M)
$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Proof:&lt;/strong&gt; We&#39;ll need to come up with some notation to differentiate the paddings in both
sides of the equation. For &#92;(0 &#92;lt i &#92;leq n-1&#92;), we&#39;ll write &#92;(p_i&#92;) to denote the paddings inside of
&#92;(&#92;text{dsizeof}(S, 0)&#92;), and we&#39;ll write &#92;(b_i&#92;) to denote the paddings inside of &#92;(&#92;text{dsizeof}(S, M)&#92;).
Thus, our equations become:&lt;/p&gt;
&lt;p&gt;$$
&#92;text{dsizeof}(S, 0) = s_1 + p_1 + s_2 + p_2 + &#92;ldots + s_{n-1} + p_{n-1} + s_n
$$
$$
&#92;text{dsizeof}(S, M) = s_1 + b_1 + s_2 + b_2 + &#92;ldots + s_{n-1} + b_{n-1} + s_n
$$&lt;/p&gt;
&lt;p&gt;All we need to show is that for any &#92;(i&#92;), we have &#92;(b_i = p_i&#92;), at which point we know that
&#92;(&#92;text{dsizeof}(S, 0) = &#92;text{dsizeof}(S, M)&#92;).&lt;/p&gt;
&lt;p&gt;First, recall our restrictions that each padding must satisfy. We know that for each &#92;(p_i&#92;) and
&#92;(b_i&#92;):&lt;/p&gt;
&lt;p&gt;$$
&#92;begin{align}
0 + s_1 + p_1 + &#92;ldots + s_i + p_i &#92;equiv 0 &#92;pmod{a_{i+1}} &#92;&#92;
M + s_1 + b_1 + &#92;ldots + s_i + b_i &#92;equiv 0 &#92;pmod{a_{i+1}}
&#92;end{align}
$$
$$
&#92;begin{align*}
0 &#92;leq p_i &#92;lt a_{i+1} &#92;&#92;
0 &#92;leq b_i &#92;lt a_{i+1}
&#92;end{align*}
$$&lt;/p&gt;
&lt;p&gt;However, in the case of equation (2), we know that by definition &#92;(M&#92;) is divisible by the greatest alignment
&#92;(a_{&#92;text{max}}=2^{k_{&#92;text{max}}}&#92;)
in &#92;(S&#92;). Since we know that each &#92;(a_i=2^{k_i} &#92;leq 2^{k_{&#92;text{max}}}&#92;),
that means that &#92;(M&#92;) is divisible by any &#92;({a_i}&#92;), and so &#92;(M &#92;equiv 0 &#92;pmod{a_i}&#92;) for all &#92;(i&#92;).&lt;/p&gt;
&lt;p&gt;So we can instead transform equation (2) into:&lt;/p&gt;
&lt;p&gt;$$
&#92;begin{align*}
M + s_1 + b_1 + &#92;ldots + s_i + b_i &#92;equiv 0 &#92;pmod{a_{i+1}} &#92;&#92;
0 + s_1 + b_1 + &#92;ldots + s_i + b_i &#92;equiv 0 &#92;pmod{a_{i+1}} &#92;&#92;
s_1 + b_1 + &#92;ldots + s_i + b_i &#92;equiv 0 &#92;pmod{a_{i+1}}
&#92;end{align*}
$$&lt;/p&gt;
&lt;p&gt;We now have the pair of equations below that we can do mathematical induction over to show that each &#92;(b_i = p_i&#92;):&lt;/p&gt;
&lt;p&gt;$$
&#92;begin{align}
s_1 + p_1 + &#92;ldots + s_i + p_i &#92;equiv 0 &#92;pmod{a_{i+1}} &#92;&#92;
s_1 + b_1 + &#92;ldots + s_i + b_i &#92;equiv 0 &#92;pmod{a_{i+1}}
&#92;end{align}
$$&lt;/p&gt;
&lt;p&gt;Let&#39;s start with the case of &#92;(i=1&#92;). Then we have the equations:&lt;/p&gt;
&lt;p&gt;$$
&#92;begin{align}
s_1 + p_1 &#92;equiv 0 &#92;pmod{a_2} &#92;&#92;
s_1 + b_1 &#92;equiv 0 &#92;pmod{a_2}
&#92;end{align}
$$&lt;/p&gt;
&lt;p&gt;However, since the lefthand sides of (5) and (6) are both equivalent to &#92;(0 &#92;pmod{a_2}&#92;), we can then write:
$$
&#92;begin{align}
s_1 + p_1 &#92;equiv s_1 + b_1 &#92;pmod{a_2} &#92;&#92;
p_1 &#92;equiv b_1 &#92;pmod{a_2}
&#92;end{align}
$$&lt;/p&gt;
&lt;p&gt;So we know that &#92;(p_1&#92;) and &#92;(b_1&#92;) are in the same equivalence class. However, by our constraints on the padding between
structure members, we know that &#92;(0 &#92;leq p_1 &#92;lt a_2&#92;), and &#92;(0 &#92;leq b_1 &#92;lt a_2&#92;). From there, we know that &#92;(p_1=b_1&#92;), and we are done with the base case.&lt;/p&gt;
&lt;p&gt;Now, we need to handle the induction step. We need to show that, for any &#92;(1 &#92;lt i &#92;leq n - 1&#92;), if &#92;(p_{j}=b_{j}&#92;) for all &#92;(1 &#92;leq j &#92;lt i&#92;), then
&#92;(p_{i}=b_{i}&#92;). However, we can solve this by similar techniques used to prove the base case.
Recall from equations (3) and (4) that we have:&lt;/p&gt;
&lt;p&gt;$$
&#92;begin{align*}
s_1 + p_1 + &#92;ldots + s_i + p_i &#92;equiv 0 &#92;pmod{a_{i+1}} &#92;&#92;
s_1 + b_1 + &#92;ldots + s_i + b_i &#92;equiv 0 &#92;pmod{a_{i+1}} &#92;&#92;
&#92;end{align*}
$$&lt;/p&gt;
&lt;p&gt;Once again, since the lefthand sides of (3) and (4) are both equivalent to &#92;(0 &#92;pmod{a_{i+1}}&#92;), we can set
them equal to each other:&lt;/p&gt;
&lt;p&gt;$$
&#92;begin{equation}
s_1 + b_1 + &#92;ldots + s_i + b_i &#92;equiv s_1 + p_1 + &#92;ldots + s_i + p_i  &#92;pmod{a_{i+1}}
&#92;end{equation}
$$&lt;/p&gt;
&lt;p&gt;And by the induction step we know that &#92;(b_j=p_j&#92;) for each &#92;(j&#92;), so we can
rewrite (9) by substituting each of the &#92;(b_j&#92;) on the lefthand side with &#92;(p_j&#92;):&lt;/p&gt;
&lt;p&gt;$$
&#92;begin{equation}
s_1 + p_1 + &#92;ldots + s_i + b_i &#92;equiv s_1 + p_1 + &#92;ldots + s_i + p_i  &#92;pmod{a_{i+1}}
&#92;end{equation}
$$&lt;/p&gt;
&lt;p&gt;so we can subtract the terms &#92;(s_1 + p_1 + &#92;ldots + s_i&#92;) from both sides of (10) to get:&lt;/p&gt;
&lt;p&gt;$$
&#92;begin{equation}
b_i &#92;equiv p_i &#92;pmod{a_{i+1}}
&#92;end{equation}
$$&lt;/p&gt;
&lt;p&gt;So &#92;(b_i&#92;) and &#92;(p_i&#92;) are in the same equivalence class. However, once again, because &#92;(0 &#92;leq b_i &#92;lt
a_{i+1}&#92;), and &#92;(0 &#92;leq p_i &#92;lt a_{i+1}&#92;), we know that &#92;(p_i=b_i&#92;) for any &#92;(i&#92;). That completes the induction, and since all of the paddings are
pairwise equal, we are done with the proof. &lt;span class=&quot;qed&quot;&gt;&#92;(&#92;blacksquare&#92;)&lt;/span&gt;&lt;/p&gt;
&lt;h3 id=&quot;the-equation-for-sizeof&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2025/9/math-struct-packing/#the-equation-for-sizeof&quot;&gt;&lt;span&gt;The equation for &lt;code&gt;sizeof&lt;/code&gt;&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Okay, we now have a mathematical formula for &#92;(&#92;text{dsizeof}(S,M)&#92;) and we know it&#39;s consistent when we have
certain restrictions on the memory address &#92;(M&#92;). We would like to use this to come up with an
equation for &lt;code&gt;sizeof&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This should be simple enough. Since &#92;(&#92;text{dsizeof}&#92;) is simply &lt;code&gt;sizeof&lt;/code&gt; without the
trailing padding, we can write:&lt;/p&gt;
&lt;p&gt;$$
&#92;text{sizeof}(S,M) = &#92;text{dsizeof}(S,M) + p
$$&lt;/p&gt;
&lt;p&gt;where &#92;(p&#92;) represents the trailing padding of the structure. Once again, &#92;(p&#92;) cannot be arbitrary. If we denote by &#92;(a_{&#92;text{max}}&#92;) the maximum alignment
of all structure members in &#92;(S&#92;), we must choose &#92;(p&#92;) such that &#92;(0 &#92;leq p &#92;lt
a_&#92;text{max}&#92;) and:&lt;/p&gt;
&lt;p&gt;$$
M + &#92;text{dsizeof}(S,M) + p &#92;equiv 0 &#92;pmod{a_&#92;text{max}}
$$&lt;/p&gt;
&lt;p&gt;so that in an array, the next instance of &#92;(S&#92;) will be aligned.&lt;/p&gt;
&lt;p&gt;However, recall that the above statement isn&#39;t completely correct, as it assumes that the only valid
alignment for &#92;(S&#92;) is for it to be aligned on &#92;(a_&#92;text{max}&#92;). As the discussion in
&lt;a href=&quot;https://sayansivakumaran.com/posts/2025/9/math-struct-packing/#a-potential-ambiguity-in-the-definition-of-sizeof&quot;&gt;&amp;quot;A potential ambiguity in the definition of &lt;code&gt;sizeof&lt;/code&gt;&amp;quot;&lt;/a&gt; shows,
we can have &amp;quot;valid&amp;quot; alignments of &#92;(S&#92;) that are not just the largest alignment in &#92;(S&#92;).&lt;/p&gt;
&lt;p&gt;In order to simplify things, I will again restrict this scope of this blog post - we will only study the mathematics of
structures aligned on the largest alignment of their members. Thus, the equation above becomes valid again.&lt;/p&gt;
&lt;h3 id=&quot;proving-the-consistency-of-sizeof&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2025/9/math-struct-packing/#proving-the-consistency-of-sizeof&quot;&gt;&lt;span&gt;Proving the consistency of &lt;code&gt;sizeof&lt;/code&gt;&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;We finally get to the important lemma that we need before we can even begin to think about finding
the minima of &lt;code&gt;sizeof&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lemma 2:&lt;/strong&gt; Let &#92;(M&#92;) be any memory address evenly divisible by the &#92;(a_&#92;text{max}&#92;), the largest alignment in &#92;(S&#92;).
Then we have that:
$$
&#92;text{sizeof}(S,0) = &#92;text{sizeof}(S,M)
$$
&lt;strong&gt;Proof:&lt;/strong&gt; Expanding the definition of &#92;(&#92;text{sizeof}&#92;), we have:&lt;/p&gt;
&lt;p&gt;$$
&#92;begin{align}
&#92;text{sizeof}(S,0) = &#92;text{dsizeof}(S,0) + p &#92;&#92;
&#92;text{sizeof}(S,M) = &#92;text{dsizeof}(S,M) + b
&#92;end{align}
$$&lt;/p&gt;
&lt;p&gt;where &#92;(p&#92;) and &#92;(b&#92;) respectively must satisfy the constraints:&lt;/p&gt;
&lt;p&gt;$$
&#92;begin{align}
&#92;text{dsizeof}(S,0) + p &#92;equiv 0 &#92;pmod{a_&#92;text{max}} &#92;&#92;
M + &#92;text{dsizeof}(S,M) + b &#92;equiv 0 &#92;pmod{a_&#92;text{max}}
&#92;end{align}
$$&lt;/p&gt;
&lt;p&gt;Recall that by &lt;strong&gt;Lemma 1&lt;/strong&gt; we know that &#92;(&#92;text{dsizeof}(S,0)=&#92;text{dsizeof}(S,M)&#92;), so it suffices
to show that the trailing paddings &#92;(p&#92;) and &#92;(b&#92;) are equal.&lt;/p&gt;
&lt;p&gt;By our choice of &#92;(M&#92;), we know that &#92;(M &#92;equiv 0 &#92;pmod{a_&#92;text{max}}&#92;), and so with (14) and (15) we have:&lt;/p&gt;
&lt;p&gt;$$
&#92;begin{align}
&#92;text{dsizeof}(S,0) + p &#92;equiv &#92;text{dsizeof}(S,M) + b &#92;pmod{a_&#92;text{max}} &#92;&#92;
p = b &#92;pmod{a_&#92;text{max}}
&#92;end{align}
$$&lt;/p&gt;
&lt;p&gt;And since we have both &#92;(0 &#92;leq p &#92;lt a_&#92;text{max}&#92;) and &#92;(0 &#92;leq b &#92;lt a_&#92;text{max}&#92;), we know that &#92;(p=b&#92;) and we are done. &lt;span class=&quot;qed&quot;&gt;&#92;(&#92;blacksquare&#92;)&lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;when-is-ordering-by-alignment-optimal&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2025/9/math-struct-packing/#when-is-ordering-by-alignment-optimal&quot;&gt;&lt;span&gt;When is ordering by alignment optimal?&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We finally have a good mathematical definition of &lt;code&gt;sizeof&lt;/code&gt;, and we have shown that the value of
&lt;code&gt;sizeof&lt;/code&gt; is consistent as long as we align the structure &#92;(S&#92;) on the largest alignment of its
members &#92;(a_&#92;text{max}&#92;). Let&#39;s try to find out when the value of &lt;code&gt;sizeof&lt;/code&gt; is minimized.&lt;/p&gt;
&lt;h3 id=&quot;primitive-structures&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2025/9/math-struct-packing/#primitive-structures&quot;&gt;&lt;span&gt;Primitive structures&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To keep our mathematics simple, we&#39;re going to restrict the class of structures that we study once
more. To start with, we&#39;re going to define a &lt;strong&gt;primitive&lt;/strong&gt; structure as any structure where, for
each member &#92;(m_i&#92;), we have it that &#92;(s_i = ca_i&#92;) for some &#92;(c &#92;geq 0&#92;). In other words, the
size of each structure member is a multiple of the same member&#39;s alignment.&lt;/p&gt;
&lt;p&gt;Loosely speaking, this is a structure whose members are all primitives, and so is one of the
simplest structures we can reason about. Furthermore, no structure members have &amp;quot;unusual alignments&amp;quot;
that were manually given to them by the programmer through specifiers such as &lt;code&gt;alignas&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For example, &lt;code&gt;Foo&lt;/code&gt; and &lt;code&gt;Bar&lt;/code&gt; would be primitive structures, but &lt;code&gt;Baz&lt;/code&gt; is not:&lt;/p&gt;
&lt;pre class=&quot;language-c&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Nothing out of the ordinary here, this is definitely primitive.&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; first&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;double&lt;/span&gt; second&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt; third&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// First off, recall when targeting 32-bit x86, GCC asserts that double has an alignment&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// of 4, so this specifier is not a no-op. Secondly, even though the programmer manually&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// overrides the alignment, this is still a primitive structure as the size is a multiple&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// of its alignment.&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Bar&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; first&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function&quot;&gt;alignas&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;double&lt;/span&gt; second&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// This is definitely not primitive, as (assuming we are on 32-bit or 64-bit systems),&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// 32 does not evenly divide into the double&#39;s size of 8.&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Baz&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; first&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function&quot;&gt;alignas&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;double&lt;/span&gt; second&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You might have already noticed that it is not just structures with primitive members that can be considered primitive
structures - structures containing fixed length arrays and nested structures qualify as well, as long as they weren&#39;t given
unusual alignments. However, we&#39;ll get to that later.&lt;/p&gt;
&lt;h3 id=&quot;ordering-members-of-a-primitive-structure-by-alignment-minimizes-dsizeof&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2025/9/math-struct-packing/#ordering-members-of-a-primitive-structure-by-alignment-minimizes-dsizeof&quot;&gt;&lt;span&gt;Ordering members of a primitive structure by alignment minimizes dsizeof&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;We&#39;re going to prove an intermediary lemma. I&#39;ve seen people online use this style of argument to
justify that ordering the members of a structure from largest to smallest alignment optimizes the
size, albeit in a handwavy way. We&#39;ll fill in the skipped details here.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lemma 3:&lt;/strong&gt; Let &#92;(S&#92;) be a primitive structure aligned on &#92;(a_&#92;text{max}&#92;), the largest alignment in &#92;(S&#92;).
Ordering the members of &#92;(S&#92;) from largest to smallest alignment will minimize the value of &#92;(&#92;text{dsizeof(S, M)}&#92;).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Proof:&lt;/strong&gt; Recall the definition of &#92;(&#92;text{dsizeof}(S, M)&#92;):&lt;/p&gt;
&lt;p&gt;$$
&#92;text{dsizeof}(S, M) = s_1 + p_1 + s_2 + p_2 + &#92;ldots + s_{n-1} + p_{n-1} + s_n &#92;
$$&lt;/p&gt;
&lt;p&gt;It suffices to show that ordering the members of &#92;(S&#92;) from the largest to smallest alignment
will make each of the intermediary paddings &#92;(p_i=0&#92;), for &#92;(0 &#92;lt i &#92;leq n-1&#92;). We do this by mathematical induction.&lt;/p&gt;
&lt;p&gt;First, we prove the base case. We want to show that if we choose an ordering of structure members such that &#92;(a_1 &#92;geq a_2&#92;),
then &#92;(p_1=0&#92;), where &#92;(p_1&#92;) must satisfy:&lt;/p&gt;
&lt;p&gt;$$
&#92;begin{align}
M + s_1 + p_1 &#92;equiv 0 &#92;pmod{a_2} &#92;&#92;
0 + s_1 + p_1 &#92;equiv 0 &#92;pmod{a_2} &#92;&#92;
s_1 + p_1 &#92;equiv 0 &#92;pmod{a_2}
&#92;end{align}
$$&lt;/p&gt;
&lt;p&gt;However, since &#92;(S&#92;) is a primitive structure, we know that &#92;(s_1=c_1a_1&#92;) for some
positive integer &#92;(c_1&#92;). Since &#92;(2^{k_1} = a_1 &#92;geq a_2 = 2^{k_2}&#92;), we know that &#92;(a_1&#92;) is evenly divisible by &#92;(a_2&#92;),
and thus &#92;(s_1&#92;) is evenly divisible by &#92;(a_2&#92;).&lt;/p&gt;
&lt;p&gt;However, by equation (20) we know that &#92;(p_1 &#92;equiv 0 &#92;pmod{a_2}&#92;) and since &#92;(0 &#92;leq p_1 &#92;lt
a_2&#92;) we immediately know that &#92;(p_1=0&#92;).&lt;/p&gt;
&lt;p&gt;Next, we prove the induction step. We need to show that, for any &#92;(1 &#92;lt i &#92;leq n&#92;), if &#92;(p_{j}=0&#92;) for all &#92;(1 &#92;leq j &#92;lt i&#92;), then
&#92;(p_{i}=0&#92;). Recall that &#92;(p_i&#92;) must satisfy the following:&lt;/p&gt;
&lt;p&gt;$$
&#92;begin{align}
M + s_1 + p_1 + &#92;ldots s_{i-1} + p_{i-1} + s_i + p_i &#92;equiv 0 &#92;pmod{a_{i+1}} &#92;&#92;
0 + s_1 + p_1 + &#92;ldots s_{i-1} + p_{i-1} + s_i + p_i &#92;equiv 0 &#92;pmod{a_{i+1}} &#92;&#92;
s_1 + p_1 + &#92;ldots s_{i-1} + p_{i-1} + s_i + p_i &#92;equiv 0 &#92;pmod{a_{i+1}}
&#92;end{align}
$$&lt;/p&gt;
&lt;p&gt;But since all &#92;(p_j=0&#92;), we know from equation (23) that:&lt;/p&gt;
&lt;p&gt;$$
s_1 + s_2 + &#92;ldots s_{i-1} + s_i + p_i &#92;equiv 0 &#92;pmod{a_{i+1}}
$$&lt;/p&gt;
&lt;p&gt;and since each &#92;(s_i=c_ia_i&#92;), we can rewrite the above as:&lt;/p&gt;
&lt;p&gt;$$
&#92;begin{equation}
c_1a_1 + c_2a_2 + &#92;ldots c_{i-1}a_{i-1} + c_ia_i + p_i &#92;equiv 0 &#92;pmod{a_{i+1}}
&#92;end{equation}
$$&lt;/p&gt;
&lt;p&gt;Recall that since we have chosen an order of structure members that goes from largest alignment to
smallest alignment, we also have:&lt;/p&gt;
&lt;p&gt;$$
a_1 &#92;geq a_2 &#92;geq a_3 &#92;geq &#92;ldots &#92;geq a_{i-1} &#92;geq a_i &#92;geq a_{i+1}
$$&lt;/p&gt;
&lt;p&gt;And since each alignment is a power of two, we know that &#92;(a_{i+1}&#92;) must evenly divide
&#92;(c_1a_1 + c_2a_2 + &#92;ldots c_{i-1}a_{i-1} + c_ia_i&#92;). Putting this together with equation (24)
we immediately know that:&lt;/p&gt;
&lt;p&gt;$$
p_i &#92;equiv 0 &#92;pmod{a_{i+1}}
$$&lt;/p&gt;
&lt;p&gt;and we are done, as &#92;(p_i=0&#92;) by our constraints on &#92;(p_i&#92;). &lt;span class=&quot;qed&quot;&gt;&#92;(&#92;blacksquare&#92;)&lt;/span&gt;&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;On minimizing structure size on ternary computers&lt;/summary&gt;
&lt;p&gt;
Notice that, in the above proof, the fact that each &#92;(a_i&#92;) was a power of 2 didn&#39;t play any particularly
important role, besides ensuring that &#92;(a_i&#92;) evenly divides by &#92;(a_j&#92;) if &#92;(i &#92;geq j&#92;). 
&lt;/p&gt;
&lt;p&gt;
Assuming a hypothetical ternary computer follows similar rules for alignment as today&#39;s binary
computers, that seems to imply that the above lemma would be true even if each &#92;(a_i=3^{k_i}&#92;) 
for some positive &#92;(k_i&#92;). In other words, on such a ternary computer ordering the members of a
structure from largest to smallest alignment would minimize &#92;(&#92;text{dsizeof}(S,M)&#92;).
&lt;/p&gt;
&lt;p&gt;
In fact, we could extrapolate that the above lemma would be true as long as each &#92;(a_i=b^{k_i}&#92;)
for some base &#92;(b&#92;), and so ordering the members of a primitive structure aligned on &#92;(a_&#92;text{max}&#92;) 
from largest to smallest alignment would minimize the size even on computers based on powers of &#92;(b&#92;).
&lt;/p&gt;
&lt;/details&gt;
&lt;h3 id=&quot;ordering-members-of-a-primitive-structure-by-alignment-minimizes-sizeof&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2025/9/math-struct-packing/#ordering-members-of-a-primitive-structure-by-alignment-minimizes-sizeof&quot;&gt;&lt;span&gt;Ordering members of a primitive structure by alignment minimizes sizeof&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;With &lt;strong&gt;Lemma 3&lt;/strong&gt; in our belt, proving that ordering structure members of a primitive structure by alignment will minimize &lt;code&gt;sizeof&lt;/code&gt;
becomes significantly easier.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lemma 4:&lt;/strong&gt; Let &#92;(S&#92;) be a primitive structure aligned on &#92;(a_&#92;text{max}&#92;), the largest alignment in &#92;(S&#92;).
Ordering the members of &#92;(S&#92;) from largest to smallest alignment will minimize the value of &#92;(&#92;text{sizeof}(S, M)&#92;).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Proof:&lt;/strong&gt; Let &#92;(S_&#92;alpha&#92;) be the structure formed from taking the members of &#92;(S&#92;) and
ordering them from the largest to smallest alignment, and let &#92;(S_&#92;beta&#92;) be the structure formed from
any permutation of the members of &#92;(S&#92;). We wish to prove that:&lt;/p&gt;
&lt;p&gt;$$&#92;text{sizeof}(S_&#92;alpha, M) &#92;leq &#92;text{sizeof}(S_&#92;beta, M)$$&lt;/p&gt;
&lt;p&gt;Expanding the definition of &#92;(&#92;text{sizeof}&#92;), we know that:&lt;/p&gt;
&lt;p&gt;$$
&#92;begin{align}
&#92;text{sizeof}(S_&#92;alpha,M) = &#92;text{dsizeof}(S_&#92;alpha,M) + p_&#92;alpha &#92;&#92;
&#92;text{sizeof}(S_&#92;beta,M) = &#92;text{dsizeof}(S_&#92;beta,M) + p_&#92;beta
&#92;end{align}
$$&lt;/p&gt;
&lt;p&gt;Furthermore, by our constraints on the tail padding &#92;(p_&#92;alpha&#92;), we know that:&lt;/p&gt;
&lt;p&gt;$$
&#92;begin{align}
M + &#92;text{dsizeof}(S_&#92;alpha,M) + p_&#92;alpha &#92;equiv 0 &#92;pmod{a_&#92;text{max}} &#92;&#92;
&#92;text{dsizeof}(S_&#92;alpha,M) + p_&#92;alpha &#92;equiv 0 &#92;pmod{a_&#92;text{max}} &#92;&#92;
&#92;end{align}
$$&lt;/p&gt;
&lt;p&gt;However, if we notice the lefthand side of equation (28) is just the definition of &#92;(&#92;text{sizeof}(S_&#92;alpha, M)&#92;), we
know that:&lt;/p&gt;
&lt;p&gt;$$
&#92;text{sizeof}(S_&#92;alpha, M) &#92;equiv 0 &#92;pmod{a_&#92;text{max}}
$$&lt;/p&gt;
&lt;p&gt;And in particular, it means that &#92;(&#92;text{sizeof}(S_&#92;alpha,M) = c_{&#92;alpha}a_&#92;text{max}&#92;) for some positive integer
&#92;(c_&#92;alpha&#92;). By a similar argument, we can conclude that &#92;(&#92;text{sizeof}(S_&#92;beta,M) = c_{&#92;beta}a_&#92;text{max}&#92;) for
some positive integer &#92;(c_&#92;beta&#92;).&lt;/p&gt;
&lt;p&gt;However, recall that &#92;(0 &#92;leq p_&#92;alpha &#92;lt a_&#92;text{max}&#92;), and &#92;(0 &#92;leq p_&#92;beta &#92;lt
a_&#92;text{max}&#92;). We can put this information together with equation (28) to notice that:&lt;/p&gt;
&lt;p&gt;$$
&#92;begin{equation}
(c_{&#92;alpha} - 1)a_&#92;text{max} &#92;lt &#92;text{dsizeof}(S_&#92;alpha, M) &#92;leq c_{&#92;alpha}a_&#92;text{max}
&#92;end{equation}
$$&lt;/p&gt;
&lt;p&gt;and we can copy-paste that argument to come to a similar conclusion about &#92;(&#92;text{dsizeof}(S_&#92;beta,
M)&#92;):&lt;/p&gt;
&lt;p&gt;$$
&#92;begin{equation}
(c_{&#92;beta} - 1)a_&#92;text{max} &#92;lt &#92;text{dsizeof}(S_&#92;beta, M) &#92;leq c_{&#92;beta}a_&#92;text{max}
&#92;end{equation}
$$&lt;/p&gt;
&lt;p&gt;By &lt;strong&gt;Lemma 3&lt;/strong&gt;, we know that &#92;(&#92;text{dsizeof}(S_&#92;alpha, M) &#92;leq &#92;text{dsizeof}(S_&#92;beta, M)&#92;), and if
we put that together with equations (29) and (30) we know that:&lt;/p&gt;
&lt;p&gt;$$
&#92;begin{gather}
(c_{&#92;alpha} - 1)a_&#92;text{max} &#92;lt &#92;text{dsizeof}(S_&#92;alpha, M) &#92;leq &#92;text{dsizeof}(S_&#92;beta, M) &#92;leq c_{&#92;beta}a_&#92;text{max} &#92;&#92;
(c_{&#92;alpha} - 1)a_&#92;text{max} &#92;lt c_{&#92;beta}a_&#92;text{max} &#92;&#92;
(c_{&#92;alpha} - 1) &#92;lt c_{&#92;beta}
&#92;end{gather}
$$&lt;/p&gt;
&lt;p&gt;And since &#92;(c_{&#92;alpha}&#92;) is the smallest integer greater than &#92;(c_{&#92;alpha} - 1&#92;), we in particular
have that &#92;(c_{&#92;alpha} &#92;leq c_{&#92;beta}&#92;). Thus:&lt;/p&gt;
&lt;p&gt;$$
&#92;text{sizeof}(S_&#92;alpha,M) = c_{&#92;alpha}a_&#92;text{max} &#92;leq c_{&#92;beta}a_&#92;text{max} =
&#92;text{sizeof}(S_&#92;beta,M)
$$&lt;/p&gt;
&lt;p&gt;and we are done with the proof. &lt;span class=&quot;qed&quot;&gt;&#92;(&#92;blacksquare&#92;)&lt;/span&gt;&lt;/p&gt;
&lt;h3 id=&quot;what-other-structures-can-be-classified-as-primitive-structures&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2025/9/math-struct-packing/#what-other-structures-can-be-classified-as-primitive-structures&quot;&gt;&lt;span&gt;What other structures can be classified as primitive structures?&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Remember that our only requirement for a structure to be a primitive structure is that
all members &#92;(m_i&#92;) satisfy &#92;(s_i = ca_i&#92;) for some &#92;(c &#92;geq 0&#92;).&lt;/p&gt;
&lt;p&gt;If a member is a primitive data type, these conditions are surely true. But these conditions also
hold if a structure member is a structure itself. This is because the starting address of a
structure &#92;(S&#92;) is always some multiple of &#92;(a_&#92;text{max}&#92;), and since we choose trailing
padding for the structure so that the structure ends on a multiple of &#92;(a_&#92;text{max}&#92;), the
difference between the starting and ending memory addresses of &#92;(S&#92;) reveals that the size of
&#92;(S&#92;) is also a multiple of &#92;(a_&#92;text{max}&#92;).&lt;/p&gt;
&lt;p&gt;The above conditions also hold true if a structure member is a fixed length array of primitive
members. This is because the alignment of the array is just the alignment of the primitive member
itself, and the size of the array is just a multiple of the size of the primitive member.&lt;/p&gt;
&lt;p&gt;In other words, &lt;strong&gt;Lemma 4&lt;/strong&gt; is applicable to a wider variety of structures than just those whose
members are primitive data types.&lt;/p&gt;
&lt;h3 id=&quot;counterexample-to-the-ordering-by-alignment-algorithm&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2025/9/math-struct-packing/#counterexample-to-the-ordering-by-alignment-algorithm&quot;&gt;&lt;span&gt;Counterexample to the &#39;ordering by alignment&#39; algorithm&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;It&#39;s easy to generate a counter example for why the &#39;ordering by alignment&#39; algorithm doesn&#39;t always
minimize the size of a structure. For example, consider the following structure on a 32-bit system:&lt;/p&gt;
&lt;pre class=&quot;language-c&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;__attribute__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;aligned&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; someInt&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;__attribute__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;aligned&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;double&lt;/span&gt; someDouble&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;short&lt;/span&gt; someShort&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is clear that the members are sorted by alignment, but we can find a layout of &lt;code&gt;Foo&lt;/code&gt; that is
smaller than the layout found previously:&lt;/p&gt;
&lt;pre class=&quot;language-c&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;__attribute__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;aligned&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; someInt&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;short&lt;/span&gt; someShort&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;__attribute__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;aligned&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;double&lt;/span&gt; someDouble&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can try &lt;a href=&quot;https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:&#39;1&#39;,fontScale:14,fontUsePx:&#39;0&#39;,j:1,lang:___c,selection:(endColumn:1,endLineNumber:20,positionColumn:1,positionLineNumber:20,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:&#39;%23include+%3Cstdio.h%3E%0A%0Astruct+FooInefficient+%7B%0A++++__attribute__((aligned(8)))+int+someInt%3B%0A++++__attribute__((aligned(8)))+double+someDouble%3B%0A++++short+someShort%3B%0A%7D%3B%0A%0Astruct+Foo+%7B%0A++++__attribute__((aligned(8)))+int+someInt%3B%0A++++short+someShort%3B%0A++++__attribute__((aligned(8)))+double+someDouble%3B%0A%7D%3B%0A%0Aint+main(void)+%7B%0A++++printf(%22Size+of+FooInefficient:+%25zu%5Cn%22,+sizeof(struct+FooInefficient))%3B%0A++++printf(%22Size+of+Foo:+%25zu%5Cn%22,+sizeof(struct+Foo))%3B%0A++++return+0%3B%0A%7D%0A&#39;),l:&#39;5&#39;,n:&#39;0&#39;,o:&#39;C+source+%231&#39;,t:&#39;0&#39;)),k:45.36247334754797,l:&#39;4&#39;,n:&#39;0&#39;,o:&#39;&#39;,s:0,t:&#39;0&#39;),(g:!((h:executor,i:(argsPanelShown:&#39;1&#39;,compilationPanelShown:&#39;0&#39;,compiler:cclang2010,compilerName:&#39;&#39;,compilerOutShown:&#39;0&#39;,execArgs:&#39;&#39;,execStdin:&#39;&#39;,fontScale:14,fontUsePx:&#39;0&#39;,j:1,lang:___c,libs:!(),options:&#39;&#39;,overrides:!(),runtimeTools:!(),source:1,stdinPanelShown:&#39;1&#39;,wrap:&#39;1&#39;),l:&#39;5&#39;,n:&#39;0&#39;,o:&#39;Executor+x86-64+clang+20.1.0+(C,+Editor+%231)&#39;,t:&#39;0&#39;)),header:(),k:26.22601279317697,l:&#39;4&#39;,n:&#39;0&#39;,o:&#39;&#39;,s:0,t:&#39;0&#39;),(g:!((h:executor,i:(argsPanelShown:&#39;1&#39;,compilationPanelShown:&#39;0&#39;,compiler:cclang2010,compilerName:&#39;&#39;,compilerOutShown:&#39;0&#39;,execArgs:&#39;&#39;,execStdin:&#39;&#39;,fontScale:14,fontUsePx:&#39;0&#39;,j:2,lang:___c,libs:!(),options:&#39;-m32&#39;,overrides:!(),runtimeTools:!(),source:1,stdinPanelShown:&#39;1&#39;,wrap:&#39;1&#39;),l:&#39;5&#39;,n:&#39;0&#39;,o:&#39;Executor+x86-64+clang+20.1.0+(C,+Editor+%231)&#39;,t:&#39;0&#39;)),header:(),k:28.411513859275054,l:&#39;4&#39;,n:&#39;0&#39;,o:&#39;&#39;,s:0,t:&#39;0&#39;)),l:&#39;2&#39;,n:&#39;0&#39;,o:&#39;&#39;,t:&#39;0&#39;)),version:4&quot;&gt;both of these examples on Godbolt&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This might imply that some kind of &amp;quot;gap-filling&amp;quot; algorithm would always give the optimal output.
However, you have to be careful here - it is possible that &amp;quot;filling the gap&amp;quot; earlier might result in
an unfillable gap later that&#39;s larger than the gap we were trying to fill. Clang attempts to write
an algorithm like this, and while it&#39;s mostly correct, we can still find structures where it fails
to find the optimal size.&lt;/p&gt;
&lt;h2 id=&quot;counterexample-to-clangs-optin-performance-padding-analyzer&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2025/9/math-struct-packing/#counterexample-to-clangs-optin-performance-padding-analyzer&quot;&gt;&lt;span&gt;Counterexample to Clang&#39;s optin.performance.Padding Analyzer&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;As mentioned before, Clang comes with an &lt;a href=&quot;https://clang.llvm.org/docs/analyzer/checkers.html#optin-performance-padding&quot;&gt;optional analyzer that will attempt to check for
excessively padded structures&lt;/a&gt;.
The comments in the &lt;a href=&quot;https://github.com/llvm/llvm-project/blob/main/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp#L230&quot;&gt;optin.performance.Padding implementation&lt;/a&gt;
gives us hints at what it tries to do.&lt;/p&gt;
&lt;p&gt;First, here is the promised counterexample on x86-64. The construction is admittedly contrived, and I&#39;m not
sure if there are any real life structures that would have a shape similar to it. In
any case, we know that Clang&#39;s algorithm is not always correct (but is probably good enough for the
vast majority of usecases).&lt;/p&gt;
&lt;p&gt;I tried to get the static checkers working in Godbolt, but failed to for some reason.
So I hope you&#39;ll be willing to try this on your own machine.&lt;/p&gt;
&lt;pre class=&quot;language-c&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;lt;stdint.h&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;lt;stdio.h&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;__attribute__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;aligned&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;uint32_t&lt;/span&gt; id&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;__attribute__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;aligned&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;uint8_t&lt;/span&gt; flags&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token class-name&quot;&gt;uint16_t&lt;/span&gt; foo&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token class-name&quot;&gt;uint16_t&lt;/span&gt; bar&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token class-name&quot;&gt;uint16_t&lt;/span&gt; blah&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;FooInefficient&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;__attribute__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;aligned&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;uint32_t&lt;/span&gt; id&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token class-name&quot;&gt;uint16_t&lt;/span&gt; foo&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token class-name&quot;&gt;uint16_t&lt;/span&gt; bar&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token class-name&quot;&gt;uint16_t&lt;/span&gt; blah&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;__attribute__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;aligned&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;uint8_t&lt;/span&gt; flags&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// Clearly &quot;inefficient&quot; structure to test that clang&#39;s&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// static analyzer is running at all.&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Baz&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt; firstChar&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;double&lt;/span&gt; firstDouble&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt; secondChar&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Size of struct Foo: %zu&#92;n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Size of struct FooInefficient: %zu&#92;n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;FooInefficient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To run the &lt;code&gt;clang&lt;/code&gt; padding checker, you can invoke the following command, assuming you copied the
above code into the file &lt;code&gt;main.c&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;clang &lt;span class=&quot;token parameter variable&quot;&gt;--analyze&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-Xclang&lt;/span&gt; -analyzer-checker&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;optin.performance.Padding &lt;span class=&quot;token parameter variable&quot;&gt;-Xclang&lt;/span&gt; -analyzer-config &lt;span class=&quot;token parameter variable&quot;&gt;-Xclang&lt;/span&gt; optin.performance.Padding:AllowedPad&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;  main.c&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On my x86-64 machine, when using clang version 20.1.8, notice how there are only warnings for the structure &lt;code&gt;Baz&lt;/code&gt;, and none for &lt;code&gt;FooInefficient&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;$ clang &lt;span class=&quot;token parameter variable&quot;&gt;--analyze&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-Xclang&lt;/span&gt; -analyzer-checker&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;optin.performance.Padding &lt;span class=&quot;token parameter variable&quot;&gt;-Xclang&lt;/span&gt; -analyzer-config &lt;span class=&quot;token parameter variable&quot;&gt;-Xclang&lt;/span&gt; optin.performance.Padding:AllowedPad&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;  main.c&lt;br /&gt;main.c:24:8: warning: Excessive padding &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;struct Baz&#39;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt; padding bytes, where &lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt; is optimal&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;. Optimal fields order: firstDouble, firstChar, secondChar, consider reordering the fields or adding explicit padding members &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;optin.performance.Padding&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br /&gt;   &lt;span class=&quot;token number&quot;&gt;24&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; struct Baz &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; ~~~~~~~^~~~~&lt;br /&gt;   &lt;span class=&quot;token number&quot;&gt;25&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;     char firstChar&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;     ~~~~~~~~~~~~~~~&lt;br /&gt;   &lt;span class=&quot;token number&quot;&gt;26&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;     double firstDouble&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;     ~~~~~~~~~~~~~~~~~~~&lt;br /&gt;   &lt;span class=&quot;token number&quot;&gt;27&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;     char secondChar&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;     ~~~~~~~~~~~~~~~~&lt;br /&gt;   &lt;span class=&quot;token number&quot;&gt;28&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; ~&lt;br /&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; warning generated.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, if you run the compiled binary, we can see that &lt;code&gt;FooInefficient&lt;/code&gt; is clearly larger than &lt;code&gt;Foo&lt;/code&gt;, and
the static analyzer did not realize that there existed a smaller layout for &lt;code&gt;FooInefficient&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;$ ./a.out&lt;br /&gt;Size of struct Foo: &lt;span class=&quot;token number&quot;&gt;24&lt;/span&gt;&lt;br /&gt;Size of struct FooInefficient: &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;further-questions&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2025/9/math-struct-packing/#further-questions&quot;&gt;&lt;span&gt;Further Questions&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There were a couple of interesting questions to explore, but I decided against including them in
this blog post as it was already getting long.&lt;/p&gt;
&lt;h3 id=&quot;ability-of-other-field-reordering-algorithms-to-minimize-size&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2025/9/math-struct-packing/#ability-of-other-field-reordering-algorithms-to-minimize-size&quot;&gt;&lt;span&gt;Ability of other field reordering algorithms to minimize size&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;While we gave a counterexample to the correctness of Clang&#39;s algorithm, it would be interesting to
mathematically characterize a group of structures where Clang&#39;s algorithm can always minimize their
size. It would be interesting to try and analyze the algorithm of &lt;code&gt;pahole&lt;/code&gt; as well, although I
vaguely remember it not accounting for &lt;code&gt;alignas&lt;/code&gt; specifiers (you should double check, I could be
remembering incorrectly).&lt;/p&gt;
&lt;p&gt;Furthermore, the problem of reordering field members to minimize size is clearly not unique to C.
It would be interesting to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Analyze the ability of &lt;a href=&quot;https://github.com/openjdk/jdk/blob/master/src/hotspot/share/classfile/fieldLayoutBuilder.cpp&quot;&gt;Java&#39;s layout algorithm&lt;/a&gt; to minimize size
&lt;ul&gt;
&lt;li&gt;There is a &lt;a href=&quot;https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8237767&quot;&gt;thorough writeup about this in Oracle&#39;s Java Bug Database&lt;/a&gt; if you&#39;re curious.&lt;/li&gt;
&lt;li&gt;As mentioned earlier, it seems like most research into Java layout organization seems to favor layouts that are friendly to the access patterns of the program.
This is probably better for performance than purely trying to minimize size, and so perhaps this
line of questioning isn&#39;t useful.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Analyze the ability of &lt;a href=&quot;https://github.com/rust-lang/rust/blob/master/compiler/rustc_abi/src/layout.rs&quot;&gt;Rust&#39;s layout algorithm&lt;/a&gt; to minimize size
&lt;ul&gt;
&lt;li&gt;Again, there is a &lt;a href=&quot;https://camlorn.net/posts/April%202017/rust-struct-field-reordering/&quot;&gt;thorough writeup about this by Austin Hicks&lt;/a&gt; if you&#39;re curious (although probably a bit outdated).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Try to come up with a layout algorithm for C++ classes, and characterize what kind of data
structures it will create an optimal layout for.
&lt;ul&gt;
&lt;li&gt;This might be trivial to do once we know how to optimize a C structure layout, but I don&#39;t
really know enough about the memory layout of C++ classes to say.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;usefulness-of-memory-allocators-flexible-enough-to-allocate-memory-at-exotic-alignments&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2025/9/math-struct-packing/#usefulness-of-memory-allocators-flexible-enough-to-allocate-memory-at-exotic-alignments&quot;&gt;&lt;span&gt;Usefulness of memory allocators flexible enough to allocate memory at exotic alignments&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Earlier, we noticed that there are other valid alignments for a structure &#92;(S&#92;) that is not just &#92;(a_&#92;text{max}&#92;).
In particular, in our discussion in &lt;a href=&quot;https://sayansivakumaran.com/posts/2025/9/math-struct-packing/#a-potential-ambiguity-in-the-definition-of-sizeof&quot;&gt;&amp;quot;A potential ambiguity in the definition of sizeof&amp;quot;&lt;/a&gt;, we saw
that a given layout of &lt;code&gt;Foo&lt;/code&gt; could be denser depending on what memory address we started it out on.&lt;/p&gt;
&lt;p&gt;It turned out to not be useful in that case because we found a layout of &lt;code&gt;Foo&lt;/code&gt; that was just as
dense at &#92;(M &#92;equiv 0 &#92;pmod{4}&#92;) as the initial layout of &lt;code&gt;Foo&lt;/code&gt; was at &#92;(M &#92;equiv 2
&#92;pmod{4}&#92;). However, this begs another question.&lt;/p&gt;
&lt;p&gt;Suppose that a structure &#92;(S&#92;) has &amp;quot;valid alignments&amp;quot; at both memory addresses &#92;(M_&#92;alpha&#92;) and
&#92;(M_&#92;beta&#92;) such that:&lt;/p&gt;
&lt;p&gt;$$
&#92;begin{gather*}
M_&#92;alpha &#92;equiv 0 &#92;pmod{a_&#92;text{max}} &#92;&#92;
M_&#92;beta &#92;equiv b &#92;pmod{c}
&#92;end{gather*}
$$&lt;/p&gt;
&lt;p&gt;for some positive integers &#92;(b&#92;) and &#92;(c&#92;). Is it true that the minimal size that we
could find when starting &#92;(S&#92;) at &#92;(M_&#92;alpha&#92;) is equal to the minimal size that we could find
when starting &#92;(S&#92;) at &#92;(M_&#92;beta&#92;)? Can we ever find denser/smaller layouts of &#92;(S&#92;) at
&#92;(M_&#92;beta&#92;) than we could at &#92;(M_&#92;alpha&#92;)?&lt;/p&gt;
&lt;p&gt;The answer to the above question might have interesting implications on how flexible memory
allocator implementations should be!&lt;/p&gt;
</description>
      <pubDate>Fri, 01 Aug 2025 00:00:00 +0000</pubDate>
      <dc:creator>Sayan Sivakumaran</dc:creator>
      <guid>https://sayansivakumaran.com/posts/2025/9/math-struct-packing/</guid>
    </item>
    <item>
      <title>Plotting the distribution of floating point numbers</title>
      <link>https://sayansivakumaran.com/posts/2024/11/plotting-floating-point-distribution/</link>
      <description>&lt;p&gt;There is an &lt;a href=&quot;https://dwayneneed.github.io/.net/2010/05/06/fun-with-floating-point.html&quot;&gt;interesting post from 2010&lt;/a&gt;
that plotted the distribution of a custom 6-bit floating point format. I was curious what the resulting graph would
look like if we plotted IEEE single precision floating point numbers, instead. Luckily, this turns out to be
very easy using the &lt;code&gt;gnuplot&lt;/code&gt; utility!&lt;/p&gt;
&lt;p&gt;The trick is to use the &lt;code&gt;nextafterf&lt;/code&gt; &lt;a href=&quot;https://linux.die.net/man/3/nextafterf&quot;&gt;(manpage)&lt;/a&gt; function to create an enumeration
of the floating point numbers. There are too many floating point numbers to plot every single one, so we&#39;ll arbitrarily
choose to only plot every hundred-thousandth floating point number, counting up to the hundred-millionth
floating point number. We&#39;ll do this in both the positive and negative directions.&lt;/p&gt;
&lt;p&gt;Here is the code we&#39;ll use to generate the &lt;code&gt;data.txt&lt;/code&gt; file for &lt;code&gt;gnuplot&lt;/code&gt; to plot from. All we need
to do is generate a text file with two space-delimited columns. The first column will hold the
current index during iteration, and the second column will hold the decimal approximation of the
floating point number.&lt;/p&gt;
&lt;pre class=&quot;language-c&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;lt;float.h&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;lt;math.h&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;lt;stdbool.h&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;lt;stdio.h&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;lt;stdlib.h&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;token macro-name&quot;&gt;INDEX_MAX&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// Plotting every single floating point number would bloat the&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// data file way too much. Let&#39;s only plot every floating point&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// number in steps of INDEX_STEP.&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;token macro-name&quot;&gt;INDEX_STEP&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  FILE &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;file &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fopen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;data.txt&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;w&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;file&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function&quot;&gt;perror&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Failed to open &#39;data.txt&#39; for writing&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;EXIT_FAILURE&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;// Plotting positive numbers&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; index &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; current &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.0f&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;index &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; INDEX_MAX &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; current &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; HUGE_VALF&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    bool should_print &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; index &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; INDEX_STEP &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;should_print &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token function&quot;&gt;fprintf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;file&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;%d %.*g&#92;n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; index&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; FLT_DECIMAL_DIG&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; current&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token function&quot;&gt;perror&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Failed to write to &#39;data.txt&#39;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token function&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;EXIT_FAILURE&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;    current &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;nextafterf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;current&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; FLT_MAX&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    index &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;// Plotting negative numbers&lt;/span&gt;&lt;br /&gt;  index &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  current &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.0f&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;index &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; INDEX_MAX &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; current &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; HUGE_VALF&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    bool should_print &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; index &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; INDEX_STEP &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;should_print &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token function&quot;&gt;fprintf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;file&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;-%d %.*g&#92;n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; index&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; FLT_DECIMAL_DIG&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; current&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token function&quot;&gt;perror&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Failed to write to &#39;data.txt&#39;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token function&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;EXIT_FAILURE&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;    current &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;nextafterf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;current&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;FLT_MAX&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    index &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token function&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;EXIT_SUCCESS&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;details&gt;
&lt;summary&gt;What is &lt;code&gt;FLT_DECIMAL_DIG&lt;/code&gt; in the code?&lt;/summary&gt;
&lt;p&gt;Approximately paraphrasing the &lt;a href=&quot;https://open-std.org/JTC1/SC22/WG14/www/docs/n3301.pdf&quot;&gt;C23 standard (PDF)&lt;/a&gt;, it
gives us the number of digits we need to write a single precision floating point number in decimal form such that
it can be converted back into the exact same floating point number. The decimal form is not exact,
but since we can map the decimal back to precisely one floating point number, it&#39;s good enough for this graphing exercise.&lt;/p&gt;
&lt;p&gt;Thanks to &lt;a href=&quot;https://stackoverflow.com/a/19897395&quot;&gt;this stack overflow post&lt;/a&gt; which taught me about this macro.&lt;/p&gt;
&lt;/details&gt;
&lt;p&gt;After running this code, we can generate the graph using the following &lt;code&gt;gnuplot&lt;/code&gt; script:&lt;/p&gt;
&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;set title &quot;Enumeration of Floating Point Numbers using nextafterf()&quot; font &quot;,18&quot; offset 0,1&lt;br /&gt;set xlabel &quot;Index during iteration (negative values represent iteration towards -FLT&#92;&#92;&#92;_MAX)&quot; font &quot;,11&quot; offset 0,-2&lt;br /&gt;set ylabel &quot;Approximate value of nextafterf() at index&quot; offset -4,0 font &quot;,11&quot;&lt;br /&gt;unset key&lt;br /&gt;set xtics axis&lt;br /&gt;set ytics axis&lt;br /&gt;set zeroaxis&lt;br /&gt;set margin 12,12,5,5&lt;br /&gt;unset border&lt;br /&gt;set xtics -1e8,2e7,1e8&lt;br /&gt;&lt;br /&gt;plot &quot;data.txt&quot; lc 2&lt;br /&gt;pause -1 &quot;Hit any key to continue&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Putting it all together, we get the following image:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://sayansivakumaran.com/posts/resources/floating_point_distribution.webp&quot; alt=&quot;Graph named &amp;quot;Enumeration of Floating Point Numbers using nextafterf()&amp;quot; that uses a linear scale. The x-axis is labeled &amp;quot;Index during iteration (negative values represent iterations towards -FLT_MAX)&amp;quot;. The y-axis is labeled &amp;quot;Value of nextafterf() at index&amp;quot;. The shape of the graph is similar to the function y=x^3.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;With the accompanying table giving the coordinates of key points on the graph if you&#39;re curious. Note that, as
mentioned in the graph, the negative values in the &amp;quot;Index during iteration&amp;quot; column represent iterations towards &lt;code&gt;-FLT_MAX&lt;/code&gt;):&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Index during iteration&lt;/th&gt;
&lt;th&gt;Approximate value of nextafterf() at index&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;-1×10&lt;sup&gt;8&lt;/sup&gt;&lt;/td&gt;
&lt;td&gt;-2.31223412×10&lt;sup&gt;-35&lt;/sup&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-8×10&lt;sup&gt;7&lt;/sup&gt;&lt;/td&gt;
&lt;td&gt;-4.62446824×10&lt;sup&gt;-36&lt;/sup&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-6×10&lt;sup&gt;7&lt;/sup&gt;&lt;/td&gt;
&lt;td&gt;-8.67087796×10&lt;sup&gt;-37&lt;/sup&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-4×10&lt;sup&gt;7&lt;/sup&gt;&lt;/td&gt;
&lt;td&gt;-1.66296864×10&lt;sup&gt;-37&lt;/sup&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-2×10&lt;sup&gt;7&lt;/sup&gt;&lt;/td&gt;
&lt;td&gt;-3.25420516×10&lt;sup&gt;-38&lt;/sup&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2×10&lt;sup&gt;7&lt;/sup&gt;&lt;/td&gt;
&lt;td&gt;3.25420516×10&lt;sup&gt;-38&lt;/sup&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4×10&lt;sup&gt;7&lt;/sup&gt;&lt;/td&gt;
&lt;td&gt;1.66296864×10&lt;sup&gt;-37&lt;/sup&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6×10&lt;sup&gt;7&lt;/sup&gt;&lt;/td&gt;
&lt;td&gt;8.67087796×10&lt;sup&gt;-37&lt;/sup&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8×10&lt;sup&gt;7&lt;/sup&gt;&lt;/td&gt;
&lt;td&gt;4.62446824×10&lt;sup&gt;-36&lt;/sup&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1×10&lt;sup&gt;8&lt;/sup&gt;&lt;/td&gt;
&lt;td&gt;2.31223412×10&lt;sup&gt;-35&lt;/sup&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The most interesting part of this data is that we can notice the gaps get bigger between the points
the farther away we get from zero! This makes sense, as incrementing the last bit in the fractional
part of a floating point number (which is basically what takes us to the next floating point number)
gives us a larger and larger difference as the exponent for the number grows.&lt;/p&gt;
</description>
      <pubDate>Thu, 07 Nov 2024 00:00:00 +0000</pubDate>
      <dc:creator>Sayan Sivakumaran</dc:creator>
      <guid>https://sayansivakumaran.com/posts/2024/11/plotting-floating-point-distribution/</guid>
    </item>
    <item>
      <title>RIP relative addressing in x86-64</title>
      <link>https://sayansivakumaran.com/posts/2024/4/rip-relative-addressing-in-x86-64/</link>
      <description>&lt;p&gt;I was attempting to learn about how &lt;a href=&quot;https://en.wikipedia.org/wiki/Dynamic_linker&quot;&gt;dynamic linking&lt;/a&gt; worked in Unix systems, and along the way I
encountered the concept of the GOT (Global Offset Table) and PLT (Procedural Linkage Table). I
wanted to see these concepts in action for myself, so I decided to compile a very simple &#39;Hello World&#39; C
program and debug its assembly:&lt;/p&gt;
&lt;pre class=&quot;language-c&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;lt;stdio.h&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Hello World&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you&#39;re already familiar with dynamic linking, you&#39;ll know that if we don&#39;t link this statically
then the &lt;code&gt;printf&lt;/code&gt; symbol will be unresolved at compile time, and we&#39;ll need to consult the
&lt;code&gt;.got.plt&lt;/code&gt; section to figure out where the definition lives (or load it if it isn&#39;t already
accessible). Here is what that looks like in x86-64 assembly, after using &lt;code&gt;objdump -D&lt;/code&gt; on the
binary:&lt;/p&gt;
&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;0000000000001030 &amp;lt;printf@plt&amp;gt;:&lt;br /&gt;    1030:	ff 25 e2 2f 00 00    	jmp    *0x2fe2(%rip)&lt;br /&gt;    1036:	68 00 00 00 00       	push   $0x0&lt;br /&gt;    103b:	e9 e0 ff ff ff       	jmp    1020 &lt;_init+0x20&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The instruction at &lt;code&gt;1030&lt;/code&gt; is where we consult the &lt;code&gt;.got.plt&lt;/code&gt; table, but how do we resolve the
address to see where our jump instruction will take us? It turns out that this kind of addressing
mode is called &lt;strong&gt;RIP relative addressing&lt;/strong&gt; (also known as &lt;strong&gt;PC relative addressing&lt;/strong&gt;), and &lt;a href=&quot;https://www.amd.com/content/dam/amd/en/documents/processor-tech-docs/programmer-references/24594.pdf&quot;&gt;Volume 3 of the AMD64 Programmer&#39;s Manual
(PDF)&lt;/a&gt;
tells us how to resolve this in chapter 1.7:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
In 64-bit mode, addressing relative to the contents of the 64-bit instruction pointer (program
counter)—called RIP-relative addressing or PC-relative addressing—is implemented for certain
instructions. In such cases, the effective address is formed by adding the displacement to the 64-bit
RIP of the next instruction. 
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Something that is very important is that the displacement is added to the address of the &lt;em&gt;next&lt;/em&gt;
instruction, not the current one. In other words, we look at the address obtained from adding 0x1036 and 0x2fe2, giving us 0x4018.
The value at that address should either point to the &lt;code&gt;printf&lt;/code&gt; symbol, or point to the
invokation of the dynamic linker to load the needed shared object (and only then call &lt;code&gt;printf&lt;/code&gt;).&lt;/p&gt;
&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ readelf -x .got.plt a.out&lt;br /&gt;&lt;br /&gt;Hex dump of section &#39;.got.plt&#39;:&lt;br /&gt; NOTE: This section has relocations against it, but these have NOT been applied to this dump.&lt;br /&gt;  0x00004000 f83d0000 00000000 00000000 00000000 .=..............&lt;br /&gt;  0x00004010 00000000 00000000 36100000 00000000 ........6.......&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Aha! It seems that dereferencing 0x4018 resolves to 0x1036 (note that my machine is little endian), which will
jump us to the instruction right after our original jump instruction at 0x1030, as expected. From
here, the dynamic linker will take over and find the definition of &lt;code&gt;printf&lt;/code&gt; for us.&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;Other types of addressing modes&lt;/summary&gt;
While perusing &lt;a href=&quot;https://www.amd.com/content/dam/amd/en/documents/processor-tech-docs/programmer-references/24592.pdf&quot;&gt;Volume 1 of the AMD64 Programmer&#39;s Manual
(PDF)&lt;/a&gt;, I found out that there are apparently other types of addressing modes besides absolute addressing
and RIP relative addressing. I encourage you to check out chapter 2.2.3 if you&#39;re curious!
&lt;/details&gt;
</description>
      <pubDate>Thu, 18 Apr 2024 00:00:00 +0000</pubDate>
      <dc:creator>Sayan Sivakumaran</dc:creator>
      <guid>https://sayansivakumaran.com/posts/2024/4/rip-relative-addressing-in-x86-64/</guid>
    </item>
    <item>
      <title>Configuring YCM to allow the restrict keyword in header files</title>
      <link>https://sayansivakumaran.com/posts/2024/3/configuring-ycm-to-allow-restrict-keyword-in-header-files/</link>
      <description>&lt;p&gt;When doing some C development earlier today, I noticed I was getting a very particular error in vim.
Given a simple header file like this:&lt;/p&gt;
&lt;pre class=&quot;language-c&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; restrict ptr&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/ycm-core/YouCompleteMe&quot;&gt;YCM&lt;/a&gt; would give an error saying &lt;code&gt;[expected_semi_decl_list] Line 2: expected &#39;;&#39; at end of declaration list&lt;/code&gt;, even though this is perfectly valid C.&lt;/p&gt;
&lt;p&gt;The reason this happened is because my configuration of YCM was using &lt;a href=&quot;https://clangd.llvm.org/&quot;&gt;&lt;code&gt;clangd&lt;/code&gt;&lt;/a&gt; for parsing the code, and there was no &lt;code&gt;.clangd&lt;/code&gt; file specifying what types of files were in this project. Because both C and C++ have header files, &lt;code&gt;clangd&lt;/code&gt; guessed that the header file was a C++ header file.&lt;/p&gt;
&lt;p&gt;C++ doesn&#39;t have the &lt;code&gt;restrict&lt;/code&gt; keyword, and so it throws the error above. The fix is simple: make a &lt;code&gt;.clangd&lt;/code&gt; configuration file at the root of your project,
and then tell &lt;code&gt;clangd&lt;/code&gt; that we are writing in C. Something like this should do it:&lt;/p&gt;
&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;CompileFlags&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token key atrule&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;xc&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
</description>
      <pubDate>Fri, 22 Mar 2024 00:00:00 +0000</pubDate>
      <dc:creator>Sayan Sivakumaran</dc:creator>
      <guid>https://sayansivakumaran.com/posts/2024/3/configuring-ycm-to-allow-restrict-keyword-in-header-files/</guid>
    </item>
    <item>
      <title>Inspecting LLVM inlining decisions with LLVM logging</title>
      <link>https://sayansivakumaran.com/posts/2024/3/inspecting-llvm-inlining-decisions-with-llvm-logging/</link>
      <description>&lt;p&gt;I was curious about how LLVM makes decisions on whether to inline a function or not, and wanted to
get a high level overview of its strategy. Thankfully, it seems like there is some relevant
logging in &lt;a href=&quot;https://github.com/llvm/llvm-project/blob/0c423af59c971ddf1aa12d94529edf8293608157/llvm/lib/Analysis/InlineCost.cpp&quot;&gt;&lt;code&gt;InlineCost.cpp&lt;/code&gt;&lt;/a&gt; that we can take advantage of!&lt;/p&gt;
&lt;p&gt;All we have to do is compile Clang in debug mode, then invoke clang with the arguments
&lt;code&gt;-mllvm -debug&lt;/code&gt;. All this does is pass the &lt;code&gt;-debug&lt;/code&gt; flag to the &lt;code&gt;llvm&lt;/code&gt; backend, which enables
logging statements for us.&lt;/p&gt;
&lt;p&gt;For example, if we wanted to analyze why the function &lt;code&gt;foo&lt;/code&gt; may or may not be inlined below:&lt;/p&gt;
&lt;pre class=&quot;language-c&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;lt;stdio.h&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;lt;stdlib.h&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; a&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token function&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;%u &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; argc&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; argv&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;argc &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token function&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Please enter an integer.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token comment&quot;&gt;// You&#39;ll want error handling in a real application here,&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token comment&quot;&gt;// but for simplicity we&#39;re omitting it.&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;strtol&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;argv&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;  &lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We would invoke &lt;code&gt;clang main.c -mllvm -debug -O2&lt;/code&gt; and look at the outputted logs. Here are the
interesting log lines after redirecting the logs to a file:&lt;/p&gt;
&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;  Initial cost: &lt;span class=&quot;token parameter variable&quot;&gt;-35&lt;/span&gt;&lt;br /&gt;  NumConstantArgs: &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;br /&gt;  NumConstantOffsetPtrArgs: &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;br /&gt;  NumAllocaArgs: &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;br /&gt;  NumConstantPtrCmps: &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;br /&gt;  NumConstantPtrDiffs: &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;br /&gt;  NumInstructionsSimplified: &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;br /&gt;  NumInstructions: &lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt;&lt;br /&gt;  SROACostSavings: &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;br /&gt;  SROACostSavingsLost: &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;br /&gt;  LoadEliminationCost: &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;br /&gt;  ContainsNoDuplicateCall: &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;br /&gt;  Cost: &lt;span class=&quot;token number&quot;&gt;170&lt;/span&gt;&lt;br /&gt;  Threshold: &lt;span class=&quot;token number&quot;&gt;225&lt;/span&gt;&lt;br /&gt;Inlining &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cost&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;170&lt;/span&gt;, &lt;span class=&quot;token assign-left variable&quot;&gt;threshold&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;225&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;, Call:   %call2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; call i32 @foo&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i32 noundef %conv&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;, &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;range &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that the &lt;code&gt;-debug&lt;/code&gt; argument won&#39;t work if &lt;code&gt;clang&lt;/code&gt; is not compiled in debug mode.&lt;/p&gt;
</description>
      <pubDate>Wed, 20 Mar 2024 00:00:00 +0000</pubDate>
      <dc:creator>Sayan Sivakumaran</dc:creator>
      <guid>https://sayansivakumaran.com/posts/2024/3/inspecting-llvm-inlining-decisions-with-llvm-logging/</guid>
    </item>
    <item>
      <title>Storage of Compound Literals in C</title>
      <link>https://sayansivakumaran.com/posts/2024/3/storage-of-compound-literals-in-c/</link>
      <description>&lt;p&gt;Some subtle details about compound literals confused me while going through
&lt;cite&gt;Modern C&lt;/cite&gt;. For example, what do you think will be returned if we
compile and run the following code?&lt;/p&gt;
&lt;pre class=&quot;language-c&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; p &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;q&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; j&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;j &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; j &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; j&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;        q &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; p &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; j &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; p &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; q&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you read the code, you might assume that this will return 0, since &lt;code&gt;q&lt;/code&gt; should
always be pointing to the &amp;quot;old&amp;quot; value of &lt;code&gt;p&lt;/code&gt; at the end of each loop, right?&lt;/p&gt;
&lt;p&gt;It turns out that &lt;code&gt;main&lt;/code&gt; will always return 1, and the C standard offers some
clarification about what is going on here.&lt;/p&gt;
&lt;p&gt;&lt;table-of-contents&gt;&lt;/table-of-contents&gt;&lt;/p&gt;
&lt;h2 id=&quot;what-is-going-on&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2024/3/storage-of-compound-literals-in-c/#what-is-going-on&quot;&gt;&lt;span&gt;What is going on?&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If we look at the &lt;a href=&quot;https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3096.pdf&quot;&gt;C23 standard (PDF)&lt;/a&gt;,
section 6.5.2.5p17 has the following to say:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;b&gt;EXAMPLE 9:&lt;/b&gt; Each compound literal creates only a single object in a given scope.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In other words, since we only have a single compound literal expression in the code snippet
above, we only allocate space for one &lt;code&gt;struct foo&lt;/code&gt; when we enter &lt;code&gt;main&lt;/code&gt;. As we go through the for loop, each &lt;code&gt;foo&lt;/code&gt; we
initialize is placed into the same address, no matter what &lt;code&gt;j&lt;/code&gt; we initialize it with. This is
because all of the structures we initialize share the same block scope and come from the same
expression.&lt;/p&gt;
&lt;p&gt;Thus, the
two pointers share the same address at the end of &lt;code&gt;main&lt;/code&gt;, and we return 1.&lt;/p&gt;
&lt;h2 id=&quot;looking-at-the-llvm-ir&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2024/3/storage-of-compound-literals-in-c/#looking-at-the-llvm-ir&quot;&gt;&lt;span&gt;Looking at the LLVM IR&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you aren&#39;t already aware, &lt;a href=&quot;https://llvm.org/docs/LangRef.html&quot;&gt;LLVM IR&lt;/a&gt; is a very convenient way to represent assembly in an
architecture independent way. Here is an annotated output of compiling the above file with
optimization level 0:&lt;/p&gt;
&lt;pre class=&quot;language-llvm&quot;&gt;&lt;code class=&quot;language-llvm&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;%struct.foo&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;; Function Attrs: noinline nounwind optnone uwtable&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;dso_local&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;@main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;#0&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token variable&quot;&gt;%1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;alloca&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token variable&quot;&gt;%2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;alloca&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%struct.foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;             &lt;span class=&quot;token comment&quot;&gt;; struct foo* p&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token variable&quot;&gt;%3&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;alloca&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%struct.foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;             &lt;span class=&quot;token comment&quot;&gt;; struct foo* q&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token variable&quot;&gt;%4&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;alloca&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;                      &lt;span class=&quot;token comment&quot;&gt;; int j&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token variable&quot;&gt;%5&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;alloca&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%struct.foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;              &lt;span class=&quot;token comment&quot;&gt;; Compound literal address&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;store&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;store&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%struct.foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%struct.foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;store&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;br&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%6&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;:                                                &lt;span class=&quot;token comment&quot;&gt;; preds = %13, %0&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token variable&quot;&gt;%7&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token variable&quot;&gt;%8&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;icmp&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;slt&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;br&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;i1&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%9&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%16&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt;:                                                &lt;span class=&quot;token comment&quot;&gt;; preds = %6&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token variable&quot;&gt;%10&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%struct.foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%struct.foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;store&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%struct.foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%struct.foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token variable&quot;&gt;%11&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;getelementptr&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;inbounds&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%struct.foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%struct.foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token variable&quot;&gt;%12&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;store&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%12&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%11&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;store&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%struct.foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%struct.foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;br&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%13&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token number&quot;&gt;13&lt;/span&gt;:                                               &lt;span class=&quot;token comment&quot;&gt;; preds = %9&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token variable&quot;&gt;%14&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token variable&quot;&gt;%15&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;nsw&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%14&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;store&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%15&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;br&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%6&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;!llvm.loop&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;!6&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;:                                               &lt;span class=&quot;token comment&quot;&gt;; preds = %6&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token variable&quot;&gt;%17&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%struct.foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%struct.foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token variable&quot;&gt;%18&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%struct.foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%struct.foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token variable&quot;&gt;%19&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;icmp&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;eq&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%struct.foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%17&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%18&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token variable&quot;&gt;%20&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;zext&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;i1&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%19&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;i32&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;%20&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you take the time to read the code, you&#39;ll notice that &lt;code&gt;%5&lt;/code&gt; holds a pointer to a &lt;code&gt;struct foo&lt;/code&gt;.
In other words, that register holds the memory allocated for our compound literal.&lt;/p&gt;
&lt;p&gt;The body of the for loop is represented by &lt;code&gt;label 9&lt;/code&gt;, where we repeatedly update the integer in &lt;code&gt;%5&lt;/code&gt;.
We are not seeing multiple &lt;code&gt;alloca&lt;/code&gt; calls to initialize a new compound literal in the loop, which
tracks with what the C23 standard says should happen.&lt;/p&gt;
&lt;p&gt;Interestingly, it turns out that compiling the same code with &lt;code&gt;-O2&lt;/code&gt; instead of &lt;code&gt;-O0&lt;/code&gt; is enough for &lt;code&gt;clang&lt;/code&gt; to give this extremely
simplified output!&lt;/p&gt;
&lt;pre class=&quot;language-llvm&quot;&gt;&lt;code class=&quot;language-llvm&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;; Function Attrs: nofree norecurse nosync nounwind readnone uwtable&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;dso_local&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;@main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;local_unnamed_addr&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;#0&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;token type class-name&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is probably expected, but I still think it&#39;s cool that the compiler is
smart enough to take all of the code above and simplify it to this small little chunk 🙂&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;Don&#39;t know how to read LLVM IR?&lt;/summary&gt;
&lt;p&gt;
That&#39;s okay - I don&#39;t know much about it either.
&lt;/p&gt;
&lt;p&gt;
I used &lt;a href=&quot;https://www.youtube.com/watch?v=m8G_S5LwlTo&amp;t=1785s&quot;&gt;this conference talk&lt;/a&gt; to get the basics down,
at least enough to somewhat understand the emitted code above. I personally found it to be a very gentle introduction.
&lt;/p&gt;
&lt;p&gt;
Afterwards, searching for instructions that I didn&#39;t know about and taking some time to read about it
in the &lt;a href=&quot;https://llvm.org/docs/ProgrammersManual.html&quot;&gt;LLVM Programmer&#39;s Manual&lt;/a&gt; was very helpful to me.
&lt;/p&gt;
&lt;/details&gt;
&lt;h2 id=&quot;why-was-this-behavior-chosen&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2024/3/storage-of-compound-literals-in-c/#why-was-this-behavior-chosen&quot;&gt;&lt;span&gt;Why was this behavior chosen?&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I attempted to go through the &lt;a href=&quot;https://www.open-std.org/jtc1/sc22/wg14/www/wg14_document_log.htm&quot;&gt;WG 14 documents&lt;/a&gt; to find the answer. After doing some digging, I found
that the first time this was brought up was in &lt;a href=&quot;https://www.open-std.org/jtc1/sc22/wg14/www/docs/n759.htm&quot;&gt;N759&lt;/a&gt;, which brought up an issue with the C99
standard. It seems that this behavior was chosen because the alternative would introduce complexity
for implementers:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Consider the situation where a compound literal is evaluated more than once
during the lifetime of its block, such as the second compound literal in
example 8. The wording is unclear whether a new object is created each time
the compound literal is evaluated, or whether a single object is simply
reinitialized. If the former is the case, a burden will be placed on
implementations, which will now have to handle dynamic allocation with
block-related lifetime.&lt;/p&gt;
&lt;/blockquote&gt;
</description>
      <pubDate>Wed, 13 Mar 2024 00:00:00 +0000</pubDate>
      <dc:creator>Sayan Sivakumaran</dc:creator>
      <guid>https://sayansivakumaran.com/posts/2024/3/storage-of-compound-literals-in-c/</guid>
    </item>
    <item>
      <title>Experimenting with AMD64 Alignment Checks</title>
      <link>https://sayansivakumaran.com/posts/2024/3/experimenting-with-amd64-alignment-checks/</link>
      <description>&lt;p&gt;While going through the &lt;cite&gt;&lt;a href=&quot;https://gustedt.gitlabpages.inria.fr/modern-c/&quot;&gt;Modern
C&lt;/a&gt;&lt;/cite&gt; book, the author mentioned a
very cool blog post by Ygdrasil that showed &lt;a href=&quot;https://orchistro.tistory.com/206&quot;&gt;how to enable alignment checks for
Intel x86 processors&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I&#39;ve heard in some casual conversations that data alignment is largely not
relevant for Intel and AMD processors anymore, although I don&#39;t have the
personal experience or expertise to verify the truth of that! However, naively
running the &lt;a href=&quot;https://lemire.me/blog/2012/05/31/data-alignment-for-speed-myth-or-reality/&quot;&gt;tests in this blog
post&lt;/a&gt;
showed that misaligned accesses were consistently around 10% slower on my
machine, so I guess it isn&#39;t obvious to me that the claim is true (or if I did
something wrong in my tests).&lt;/p&gt;
&lt;p&gt;In any case, I wanted to try enabling this check for myself just to see what
would happen.&lt;/p&gt;
&lt;p&gt;&lt;table-of-contents&gt;&lt;/table-of-contents&gt;&lt;/p&gt;
&lt;h2 id=&quot;the-code&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2024/3/experimenting-with-amd64-alignment-checks/#the-code&quot;&gt;&lt;span&gt;The Code&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This code is more or less copy-pasted from the code in &lt;cite&gt;Modern C&lt;/cite&gt; and Ygdrasil&#39;s
blog post.&lt;/p&gt;
&lt;pre class=&quot;language-c&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;lt;stdio.h&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;union&lt;/span&gt; DoubleInspect &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;double&lt;/span&gt; val&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt; buf&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function&quot;&gt;__asm__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;pushf&#92;n&quot;&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token string&quot;&gt;&quot;orl $0x40000, (%rsp)&#92;n&quot;&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token string&quot;&gt;&quot;popf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;union&lt;/span&gt; DoubleInspect inspect &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;val &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;base address:&#92;t%p&#92;n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;inspect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;buf&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class=&quot;token comment&quot;&gt;// Let&#39;s do explicit flushes since we don&#39;t know if crashing&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token comment&quot;&gt;// will automatically flush the buffers or not.&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;size_t&lt;/span&gt; offset &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; offset&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; offset &lt;span class=&quot;token operator&quot;&gt;/=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token function&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;offset:&#92;t%zu&#92;n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; offset&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token function&quot;&gt;fflush&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;stdout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span class=&quot;token keyword&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; misaligned_pointer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;inspect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;buf&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;offset&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token function&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;address with offset:&#92;t%p&#92;n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; misaligned_pointer&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token function&quot;&gt;fflush&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;stdout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span class=&quot;token function&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;value at address:&#92;t%f&#92;n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;misaligned_pointer&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token function&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&#92;n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token function&quot;&gt;fflush&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;stdout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The most important parts of the code above are the inline assembly instructions.&lt;/p&gt;
&lt;pre class=&quot;language-c&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;token function&quot;&gt;__asm__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;pushf&#92;n&quot;&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token string&quot;&gt;&quot;orl $0x40000, (%rsp)&#92;n&quot;&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token string&quot;&gt;&quot;popf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While Ygdrasil&#39;s blog post is specific to Intel processors, the trick they talk
about thankfully seems to be supported by AMD processors, too! One can verify
this by taking a look at the &lt;a href=&quot;https://www.amd.com/content/dam/amd/en/documents/processor-tech-docs/programmer-references/24593.pdf&quot;&gt;AMD64 programmer&#39;s
manual&lt;/a&gt; —
all we&#39;re doing is setting bit 18 of the RFLAGs register.&lt;/p&gt;
&lt;h2 id=&quot;running-the-code&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2024/3/experimenting-with-amd64-alignment-checks/#running-the-code&quot;&gt;&lt;span&gt;Running the Code&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Strangely, when running the above program, &lt;code&gt;glibc&lt;/code&gt; seems to immediately crash with this check
enabled. I assume the library does some special things on x86-64 processors, and so assumes that
misaligned data will never crash.&lt;/p&gt;
&lt;p&gt;This even happens when running an extremely minimal &lt;code&gt;hello.c&lt;/code&gt; file:&lt;/p&gt;
&lt;pre class=&quot;language-c&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;lt;stdio.h&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function&quot;&gt;__asm__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;pushf&#92;n&quot;&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token string&quot;&gt;&quot;orl $0x40000, (%rsp)&#92;n&quot;&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token string&quot;&gt;&quot;popf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class=&quot;token function&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Hi&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here is the backtrace from running the above program in &lt;code&gt;gdb&lt;/code&gt; if you&#39;re curious. It seems that we
crash at &lt;a href=&quot;https://sourceware.org/git/?p=glibc.git;a=blob;f=stdio-common/vfprintf-internal.c;h=771beca9bf71f4c817800fb44c45c19ec1e3a9d3;hb=HEAD#l635&quot;&gt;this line of code&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Program received signal SIGBUS, Bus error.&lt;br /&gt;0x00007ffff7e37078 in __printf_buffer (buf=buf@entry=0x7fffffffd8b0, format=format@entry=0x7ffff7fc0004 &quot;Hi&quot;, ap=ap@entry=0x7fffffffd9a8, mode_flags=mode_flags@entry=0) at vfprintf-internal.c:638&lt;br /&gt;638	  __va_copy (ap_save, ap);&lt;br /&gt;(gdb) bt&lt;br /&gt;#0  0x00007ffff7e37078 in __printf_buffer (buf=buf@entry=0x7fffffffd8b0, format=format@entry=0x7ffff7fc0004 &quot;Hi&quot;, ap=ap@entry=0x7fffffffd9a8, mode_flags=mode_flags@entry=0)&lt;br /&gt;    at vfprintf-internal.c:638&lt;br /&gt;#1  0x00007ffff7e392c1 in __vfprintf_internal (s=0x7ffff7fae7a0 &lt;_IO_2_1_stdout_&gt;, format=0x7ffff7fc0004 &quot;Hi&quot;, ap=ap@entry=0x7fffffffd9a8, mode_flags=mode_flags@entry=0)&lt;br /&gt;    at vfprintf-internal.c:1544&lt;br /&gt;#2  0x00007ffff7e2f162 in __printf (format=&amp;lt;optimized out&amp;gt;) at printf.c:33&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We get a similar crash if we replace the call to &lt;code&gt;printf&lt;/code&gt; with a call to &lt;code&gt;puts&lt;/code&gt;.
Is this a problem? I&#39;m not too sure if this is a crash the library maintainers need to care about.
But it does make enabling the alignment check useless if you link against &lt;code&gt;glibc&lt;/code&gt;
and use &lt;code&gt;printf&lt;/code&gt; in your program (at least on my machine).&lt;/p&gt;
&lt;p&gt;If we remove all printing functions from our first code example instead:&lt;/p&gt;
&lt;pre class=&quot;language-c&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;union&lt;/span&gt; DoubleInspect &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;double&lt;/span&gt; val&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt; buf&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function&quot;&gt;__asm__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;pushf&#92;n&quot;&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token string&quot;&gt;&quot;orl $0x40000, (%rsp)&#92;n&quot;&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token string&quot;&gt;&quot;popf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;union&lt;/span&gt; DoubleInspect inspect &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;val &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;size_t&lt;/span&gt; offset &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; offset&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; offset &lt;span class=&quot;token operator&quot;&gt;/=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token keyword&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; misaligned_pointer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;inspect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;buf&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;offset&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;misaligned_pointer &lt;span class=&quot;token operator&quot;&gt;*=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;misaligned_pointer&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And we then compile with debug symbols, we do crash when &lt;code&gt;misaligned_pointer&lt;/code&gt; is dereferenced, as
expected.&lt;/p&gt;
&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;(gdb) r&lt;br /&gt;Starting program: /home/sayan/Development/experiments/c/alignment/a.out&lt;br /&gt;[Thread debugging using libthread_db enabled]&lt;br /&gt;Using host libthread_db library &quot;/lib/x86_64-linux-gnu/libthread_db.so.1&quot;.&lt;br /&gt;&lt;br /&gt;Program received signal SIGBUS, Bus error.&lt;br /&gt;0x00005555555551a4 in main () at main-minimal.c:18&lt;br /&gt;18	        *misaligned_pointer *= *misaligned_pointer;&lt;br /&gt;(gdb) p offset&lt;br /&gt;$1 = 4&lt;br /&gt;(gdb)&lt;/code&gt;&lt;/pre&gt;
</description>
      <pubDate>Sun, 03 Mar 2024 00:00:00 +0000</pubDate>
      <dc:creator>Sayan Sivakumaran</dc:creator>
      <guid>https://sayansivakumaran.com/posts/2024/3/experimenting-with-amd64-alignment-checks/</guid>
    </item>
    <item>
      <title>What exactly is the accessibility API?</title>
      <link>https://sayansivakumaran.com/posts/2023/8/what-exactly-is-the-accessibility-api/</link>
      <description>&lt;aside&gt;
This blog post duplicates my talk &quot;What exactly is the accessibility API?&quot; at &lt;a href=&quot;https://www.devfestwi.com/&quot;&gt;Devfest Wisconsin&lt;/a&gt;, except with technical detail and comments that I opted to leave out of the presentation. Here are &lt;a href=&quot;https://docs.google.com/presentation/d/1D0OptHHrdh4meLcprjnFMERFrN_wc12t7Y9A-GNmW3A/edit#slide=id.p&quot;&gt;the slides&lt;/a&gt; if you really want them, though.
&lt;/aside&gt;
&lt;p&gt;I notice that a lot of content introducing the accessibility API (&lt;a href=&quot;https://en.wikipedia.org/wiki/API&quot;&gt;Application Programming Interface&lt;/a&gt;) only talk about how it might be used by screen readers. I&#39;m guessing this is one of the reasons that people don&#39;t ever consider voice control or other assistive technologies when doing accessibility testing, and why people add questionable labels to certain controls.&lt;/p&gt;
&lt;p&gt;I wrote this blog post to try and give an introduction to the accessibility API that doesn&#39;t only consider screen readers, and introduces what kinds of things a browser considers when generating an accessibility tree for the accessibility API. I hope I can share what I learned over the past year of doing open source work and digging into native accessibility code.&lt;/p&gt;
&lt;p&gt;&lt;table-of-contents&gt;&lt;/table-of-contents&gt;&lt;/p&gt;
&lt;h2 id=&quot;foreword&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/8/what-exactly-is-the-accessibility-api/#foreword&quot;&gt;&lt;span&gt;Foreword&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;All the content in this blog post will assume the basics of HTML and CSS. I will link to C++ or Python source code that you can explore if you like, but it is by no means required to understand this topic at a high level.&lt;/p&gt;
&lt;p&gt;While any browser source code I link to will be biased to Chromium, any browser behavior I mention below should be true for the following major browsers, unless explicitly mentioned otherwise:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Chromium (Version 116)&lt;/li&gt;
&lt;li&gt;Firefox (Version 116)&lt;/li&gt;
&lt;li&gt;Safari (Version 16.6)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Finally, all links to source code, whether it be to browsers or assistive technology or otherwise, will be locked to a specific revision — their latest revision as of the time of this writing. I do this so future readers won&#39;t experience the phenomena where I&#39;m pointing to a line of code and that specific line of code doesn&#39;t do what I point out anymore.&lt;/p&gt;
&lt;h2 id=&quot;what-is-assistive-technology&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/8/what-exactly-is-the-accessibility-api/#what-is-assistive-technology&quot;&gt;&lt;span&gt;What is assistive technology?&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before introducing the concept of an accessibility API, it&#39;s important to think about what kind of technology we&#39;re trying to support.&lt;/p&gt;
&lt;p&gt;Assistive technology is any piece of technology that disabled people use to improve their quality of life. This can include things like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Wheelchairs&lt;/li&gt;
&lt;li&gt;Refreshable braille displays&lt;/li&gt;
&lt;li&gt;Magnification software&lt;/li&gt;
&lt;li&gt;Screen readers&lt;/li&gt;
&lt;li&gt;Voice recognition software&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For the purpose of this post, let&#39;s focus on the last two bullet points in more detail.&lt;/p&gt;
&lt;h3 id=&quot;what-is-a-screen-reader&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/8/what-exactly-is-the-accessibility-api/#what-is-a-screen-reader&quot;&gt;&lt;span&gt;What is a screen reader?&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Wikipedia gives a decent summary:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A screen reader is a form of assistive technology (AT) that renders text and image content as speech or braille output. Screen readers are essential to people who are blind, and are useful to people who are visually impaired, illiterate, or have a learning disability.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;- &lt;a href=&quot;https://en.wikipedia.org/wiki/Screen_reader&quot;&gt;Wikipedia&#39;s Screen Reader Article&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;There are different popular screen readers depending on the platform you are on.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;JAWS and NVDA on Windows&lt;/li&gt;
&lt;li&gt;VoiceOver on Mac and iOS&lt;/li&gt;
&lt;li&gt;Orca on Linux&lt;/li&gt;
&lt;li&gt;Talkback on Android&lt;/li&gt;
&lt;li&gt;ChromeVox on ChromeOS&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Regardless of platform, however, screen readers are able to do things like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Announce what control is currently focused&lt;/li&gt;
&lt;li&gt;Announce any relevant state information of the control (Is it checked? Is it expanded?)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;along with any other visually important information that a screen reader user should know.&lt;/p&gt;
&lt;aside&gt;
For the sake of brevity, I will often mention that screen readers &quot;announce&quot; something, but as previously mentioned screen readers are just machines that generate text from a user interface. They can also be hooked up to refreshable braille displays to provide braille output, instead of just announcing something.
&lt;/aside&gt;
&lt;p&gt;Screen readers are highly customizable. For example, screen reader users can control how fast or slow text is announced, or filter out specific bits of information they might not care about.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://youtu.be/y0m7VEHoXMI?t=360&quot;&gt;Demo of NVDA by Deque Systems&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;what-is-voice-recognition-software&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/8/what-exactly-is-the-accessibility-api/#what-is-voice-recognition-software&quot;&gt;&lt;span&gt;What is voice recognition software?&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Voice recognition software is a form of assistive technology that allows a user to interact with their machine through voice commands. For example, if there is a link called &amp;quot;See my projects&amp;quot;, such as the dummy link below:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;javascript:void(0);&quot;&gt;See my projects&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;a voice recognition user should be able to say something like &amp;quot;Click see my projects&amp;quot;, and the software will programmatically click the link. The user can also do things such as dictate text to type into some editable text area, and the voice recognition software will automatically enter that text for the user.&lt;/p&gt;
&lt;p&gt;Some examples of voice recognition software:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Windows Speech Recognition and Dragon Speech Recognition on Windows&lt;/li&gt;
&lt;li&gt;Voice Control on Mac and iOS&lt;/li&gt;
&lt;li&gt;Voice Access on Android&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=7y85YDMRpTU&amp;ab_channel=NuanceCommunications%2CInc.&quot;&gt;Demo of Dragon by Nuance Communications&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;what-information-does-assistive-technology-need-to-gather&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/8/what-exactly-is-the-accessibility-api/#what-information-does-assistive-technology-need-to-gather&quot;&gt;&lt;span&gt;What information does assistive technology need to gather?&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Suppose that we are developers for screen readers or voice recognition software. What kind of information would we need from any application that wants to support us?&lt;/p&gt;
&lt;p&gt;Screen readers would need a way to do the following for any application:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Programmatically access all user interface (UI) elements.&lt;/li&gt;
&lt;li&gt;Query for the name of a UI element: if focused, what should I announce?&lt;/li&gt;
&lt;li&gt;Query for what kind of UI element something is: Is it a button? Is it a link?&lt;/li&gt;
&lt;li&gt;Query for any state of those UI elements: Is it checked? Is it pressed?&lt;/li&gt;
&lt;li&gt;Programmatically ask the application to activate an element that might not be currently focused: for instance, to programmatically activate a control under a &lt;a href=&quot;https://support.freedomscientific.com/teachers/lessons/4.2.3_VirtualPCCursor.htm&quot;&gt;virtual cursor&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Voice recognition software would need a way to do the following for any application:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Programmatically access all interactive UI elements of an application.&lt;/li&gt;
&lt;li&gt;Query for the name of a UI element: is my user trying to activate this element?&lt;/li&gt;
&lt;li&gt;Programmatically ask the application to activate an element for us: for instance, if the user commands us to activate a button that isn&#39;t currently focused.&lt;/li&gt;
&lt;li&gt;Programmatically insert text somewhere in the application if the user starts dictating.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are very similar asks. We are asking for an API that lets us programmatically read and interact with an application, and that is precisely what an accessibility API is.&lt;/p&gt;
&lt;h2 id=&quot;what-is-the-accessibility-api&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/8/what-exactly-is-the-accessibility-api/#what-is-the-accessibility-api&quot;&gt;&lt;span&gt;What is the accessibility API?&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;As mentioned above, an accessibility API allows for a consumer to do two main things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Programmatically determine what is in the UI&lt;/li&gt;
&lt;li&gt;Programmatically interact with the UI&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the accessibility API, the UI of an application is exposed as something called the &lt;strong&gt;accessibility tree&lt;/strong&gt;, with each node in the tree being some individual unit in the UI. Depending on the UI element a node represents, a consumer can query for the state of a node, or ask to programmatically take some kind of action on a node.&lt;/p&gt;
&lt;p&gt;Depending on the operating system, the accessibility API can have different implementation details, but the general idea remains the same. The average web developer does not have to concern themselves with this.&lt;/p&gt;
&lt;h3 id=&quot;what-does-an-accessibility-tree-look-like&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/8/what-exactly-is-the-accessibility-api/#what-does-an-accessibility-tree-look-like&quot;&gt;&lt;span&gt;What does an accessibility tree look like?&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;An accessibility tree is a normal tree data structure that you might explore in your computer science class. For example, in the context of the browser, suppose we have some HTML like the following:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;header&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;...&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;header&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Hello World&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;img&lt;/span&gt;&lt;br /&gt;		&lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;...&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;		&lt;span class=&quot;token attr-name&quot;&gt;alt&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;...&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;	&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;		This is a paragraph.&lt;br /&gt;		&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;span&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; This is more text. &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;span&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;footer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;...&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;footer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The browser might generate an accessibility tree similar to the following for this HTML:&lt;/p&gt;
&lt;ul class=&quot;tree&quot;&gt;
  &lt;li&gt;
    &lt;span&gt;
    root
    &lt;/span&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;span&gt;header&lt;/span&gt;&lt;/li&gt;
      &lt;li&gt;
        &lt;span&gt;main&lt;/span&gt;
      &lt;ul&gt;
        &lt;li&gt;&lt;span&gt;heading&lt;/span&gt;&lt;/li&gt;
        &lt;li&gt;&lt;span&gt;image&lt;/span&gt;&lt;/li&gt;
        &lt;li&gt;&lt;span&gt;paragraph&lt;/span&gt;&lt;/li&gt;
      &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;span&gt;footer&lt;/span&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each of these nodes may have a plethora of accessibility-related information, but we can get to that later. Notice that the accessibility tree also isn&#39;t necessarily one-to-one with the DOM tree generated from the HTML. For example, it might not be justified to give that &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; element its own accessibility node, and so it&#39;s just absorbed into the parent &lt;code&gt;paragraph&lt;/code&gt; node instead.&lt;/p&gt;
&lt;p&gt;From the above example, let&#39;s zoom in to the image node specifically. What kind of information might it have?&lt;/p&gt;
&lt;div class=&quot;ax-node&quot;&gt;
&lt;p&gt;image&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Name&lt;/dt&gt;
&lt;dd&gt;&quot;Some alt text&quot;&lt;/dd&gt;
&lt;dt&gt;Role&lt;/dt&gt;
&lt;dd&gt;Image&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Name&lt;/strong&gt;: The node will need an accessible name if the image is not decorative. This can let screen readers know what to read when encountering this image.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Role&lt;/strong&gt;: The node will need to have some kind of attribute marking what type of UI element it is. This lets assistive technologies know what kinds of actions they can take on this node, as well as what kind of information they can query on it. In this case, the node should be an image node.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If we instead take something stateful, like a checkbox:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;label&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;check&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Stay logged in&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;label&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;checkbox&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;check&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token attr-name&quot;&gt;&amp;lt;!--&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;Any&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;other&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;relevant&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;attributes...&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;/&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The accessibility node for the checkbox might look something like this:&lt;/p&gt;
&lt;div class=&quot;ax-node&quot;&gt;
&lt;p&gt;checkbox&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Name&lt;/dt&gt;
&lt;dd&gt;&quot;Stay logged in&quot;&lt;/dd&gt;
&lt;dt&gt;Role&lt;/dt&gt;
&lt;dd&gt;Checkbox&lt;/dd&gt;
&lt;dt&gt;State&lt;/dt&gt;
&lt;dd&gt;IsChecked: true&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Name&lt;/strong&gt;: Once again, the name lets the screen reader know what to announce when the checkbox is focused, and lets voice recognition software know what to click when the user says this checkbox&#39;s name.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Role&lt;/strong&gt;: Because of the role, assistive technology knows that it can query for the &amp;quot;checked&amp;quot; state of this node. It also knows that it can ask the browser to programmatically click the checkbox.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;State&lt;/strong&gt;: Allows assistive technology to query whether this checkbox is checked or not. For example, screen readers might use this to decide what to announce.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is the common trio of &lt;a href=&quot;https://www.w3.org/WAI/WCAG21/Understanding/name-role-value.html&quot;&gt;name, role, value&lt;/a&gt; which can be important to make sure your website is accessible.&lt;/p&gt;
&lt;p&gt;As far as web developers are concerned, the name, role, value, and state of a node are the main parts of the accessibility tree that you need to worry about. However, there is a lot of other information calculated in the accessibility tree that you might not be aware of. For example, if we just restrict our attention to the &lt;a href=&quot;https://learn.microsoft.com/en-us/dotnet/framework/ui-automation/ui-automation-overview&quot;&gt;UIAutomation&lt;/a&gt; accessibility API:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentboundingrectangle&quot;&gt;&lt;strong&gt;Bounding boxes&lt;/strong&gt;&lt;/a&gt;: Where is the element located on the screen?&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/dotnet/api/system.windows.automation.automationelement.cultureproperty?view=windowsdesktop-7.0&quot;&gt;&lt;strong&gt;Locale&lt;/strong&gt;&lt;/a&gt;: What language should I be interpreting this object with?&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/dotnet/api/system.windows.automation.automationelement.frameworkidproperty?view=windowsdesktop-7.0&quot;&gt;&lt;strong&gt;FrameworkId&lt;/strong&gt;&lt;/a&gt;: What is the source of this accessibility tree? Is this an accessibility tree coming from Chrome? Is this an accessibility tree coming from Microsoft PowerPoint?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Moving our attention to another accessibility API, &lt;a href=&quot;https://accessibility.linuxfoundation.org/a11yspecs/ia2/docs/html/index.html&quot;&gt;IAccessible2&lt;/a&gt;, gives us more interesting information to look at, with both examples being custom properties that don&#39;t seem to formally be part of the IAccessible2 spec:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/chromium/chromium/blob/dbeac1c32d632c85e62f5ccfefa76151996e65f3/ui/accessibility/platform/ax_platform_node_base.cc#L1462&quot;&gt;&lt;strong&gt;LayoutTable&lt;/strong&gt;&lt;/a&gt;: For the purpose of semantics, &lt;a href=&quot;https://sayansivakumaran.com/posts/2023/6/browser-table-accessibility-remediation/&quot;&gt;is this a real or fake table&lt;/a&gt;?&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/chromium/chromium/blob/dbeac1c32d632c85e62f5ccfefa76151996e65f3/ui/accessibility/platform/ax_platform_node_base.cc#L1250&quot;&gt;&lt;strong&gt;CSS Display&lt;/strong&gt;&lt;/a&gt;: What is the CSS display for this node?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There is a lot of other information that I am leaving out. While this information isn&#39;t the most important to know (although it is good practice to specify locale with &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/lang&quot;&gt;the &lt;code&gt;lang&lt;/code&gt; attribute&lt;/a&gt;), it can be useful to know that the accessibility tree can&#39;t be generated just by scanning the DOM — we need information from CSS as well.&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;Regarding CSS Display in an accessibility node&lt;/summary&gt;
&lt;p&gt;
Finding this property surprised me. I double checked the source of this data in Chromium, and it does appear to be the &lt;a href=&quot;https://github.com/chromium/chromium/blob/6d6ca9492f5c5183bbb1abdabaa4ecf2ece99a2d/third_party/blink/renderer/modules/accessibility/ax_object.cc#L1827&quot;&gt;computed CSS style for the display property&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
I tried searching for similar logic in Firefox, but wasn&#39;t able to find anything interesting &lt;a href=&quot;https://searchfox.org/mozilla-central/rev/f979f15eaeef504bfdcd27f033323d62b51986cd/accessible/generic/HyperTextAccessible.cpp#409&quot;&gt;besides this comment&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
I don&#39;t expect Safari to calculate this, since it seems to be logic specific to IAccessible2 and AT-SPI. Neither of those accessibility APIs are used in Mac products as far as I can tell.
&lt;/p&gt;
&lt;p&gt;
What is this ever used for? No idea. I naively searched for it in the NVDA and Orca codebase, and got the following hits.
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/nvaccess/nvda/blob/186a8d70717234cc48d012e390e43be7b762574b/source/NVDAObjects/IAccessible/ia2TextMozilla.py#L561&quot;&gt;NVDA CSS display usage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gitlab.gnome.org/GNOME/orca/-/blob/eaa47a3e1683ed95d8d9c7fb4dcd8bc4254d8cd6/src/orca/scripts/web/script_utilities.py#L535&quot;&gt;Orca CSS display usage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;h3 id=&quot;how-can-i-view-the-accessibility-tree&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/8/what-exactly-is-the-accessibility-api/#how-can-i-view-the-accessibility-tree&quot;&gt;&lt;span&gt;How can I view the accessibility tree?&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;You have two choices here, depending on the amount of detail that you need.&lt;/p&gt;
&lt;p&gt;The first choice is to use the browser&#39;s built-in accessibility tree viewer. You don&#39;t see the exact information that is given to assistive technology, as the information needs to be expressed in terms of the platform accessibility APIs, but it&#39;s extremely rare that you need that level of detail.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/accessibility/reference/#pane&quot;&gt;Chromium Accessibility Inspector&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://firefox-source-docs.mozilla.org/devtools-user/accessibility_inspector/&quot;&gt;Firefox Accessibility Inspector&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://support.apple.com/guide/safari-developer/view-node-properties-for-a-dom-node-dev160f70435/11.0/mac/10.13&quot;&gt;Safari Web Inspector&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;details&gt;
&lt;summary&gt;Regarding Chromium&#39;s accessibility tree inspector&lt;/summary&gt;
&lt;p&gt;The accessibility tree you see in the Chromium developer tools is what is internally known as the Blink tree. For all intents and purposes, this is a peek into the exact data that is being translated into the platform APIs - this isn&#39;t some special intermediate representation that the code makes just for the developer tools, in other words. &lt;/p&gt;
&lt;p&gt;This logic is handled in &lt;a href=&quot;https://github.com/chromium/chromium/blob/main/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.cc&quot;&gt;&lt;code&gt;InspectorAccessibilityAgent&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/details&gt;
&lt;p&gt;The second choice is to use an external tool that can display the native accessibility tree to you. You have different tools depending on your platform.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://chromium.googlesource.com/chromium/src/+/master/tools/accessibility/inspect/README.md&quot;&gt;Dump Tree Utility&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://accessibilityinsights.io/docs/windows/overview/&quot;&gt;Accessibility Insights for Windows&lt;/a&gt; (UIAutomation only)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.apple.com/library/archive/documentation/Accessibility/Conceptual/AccessibilityMacOSX/OSXAXTestingApps.html&quot;&gt;Accessibility Inspector on OS X&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://help.gnome.org/users/accerciser/stable/introduction.html.en&quot;&gt;Accerciser&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These tools are a good way to play around with the native accessibility APIs if you want to take the time. I think it&#39;s very rare these tools are useful for web development, though.&lt;/p&gt;
&lt;h2 id=&quot;what-technologies-use-the-accessibility-api&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/8/what-exactly-is-the-accessibility-api/#what-technologies-use-the-accessibility-api&quot;&gt;&lt;span&gt;What technologies use the accessibility API?&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Remember that an accessibility API allows you to do two things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It allows you to programmatically read off the UI of an application through an exposed accessibility tree.&lt;/li&gt;
&lt;li&gt;It allows you to programmatically interact with the UI of an application through nodes on the exposed accessibility tree.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As previously discussed, this allows screen readers to know what to read out when interacting with a page, and allows voice recognition software to know how to respond to specific voice commands from the user. However, there are lots of other assistive and non-assistive technologies that use the accessibility API.&lt;/p&gt;
&lt;aside&gt;
&lt;p&gt;
For the following links below, you&#39;ll want to copy the link address and paste it into your navigation toolbar rather than trying to activate the link. It seems that Chromium browsers won&#39;t let you link directly to the &lt;a href=&quot;about://histograms&quot;&gt;about://histograms&lt;/a&gt; page, and you&#39;ll instead get an empty page.
&lt;/p&gt;
&lt;p&gt;
Furthermore, depending on how powerful your CPU is, I highly recommend you don&#39;t navigate directly to the &lt;a href=&quot;about://histograms&quot;&gt;about://histograms&lt;/a&gt; page, and instead navigate to the specific histograms I talk about below, listed here for convenience:
&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;about://histograms/#Accessibility.Performance.HandleAXEvents&quot;&gt;about://histograms/#Accessibility.Performance.HandleAXEvents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;about://histograms/#Accessibility.WinAPIs&quot;&gt;about://histograms/#Accessibility.WinAPIs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The performance on the general &lt;a href=&quot;about://histograms&quot;&gt;about://histograms&lt;/a&gt; page is terrible when I&#39;m using anything that queries the accessibility tree, even on my computer which has a relatively expensive CPU (Ryzen 5950x).&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;To find out what applications use the accessibility API, we can use the &lt;a href=&quot;about://histograms&quot;&gt;about://histograms&lt;/a&gt; page on a Chromium based browser to determine whether the browser is calculating accessibility information or not (for performance purposes, the browser doesn&#39;t kick off accessibility-related code until it has to).&lt;/p&gt;
&lt;p&gt;As a a decent hueristic, if the &lt;a href=&quot;chrome://histograms/#Accessibility.Performance.HandleAXEvents&quot;&gt;histogram for HandleAXEvents&lt;/a&gt; has more than one data sample, we know that accessibility must have been turned on for some duration while the Chromium browser was running. In other words, some application has been making calls to the accessibility API. You can use this heuristic on any platform Chromium runs on.&lt;/p&gt;
&lt;p&gt;We can do better on the Windows platform, though. On Windows, Chromium has a &lt;a href=&quot;chrome://histograms/#Accessibility.WinAPIs&quot;&gt;WinAPIs histogram&lt;/a&gt; that lets us know how many times specific Windows accessibility APIs were called. The values of the histogram correspond with &lt;a href=&quot;https://github.com/chromium/chromium/blob/dbeac1c32d632c85e62f5ccfefa76151996e65f3/ui/accessibility/platform/ax_platform_node_win.h#L44&quot;&gt;this collection of enums&lt;/a&gt;. So not only do we know if an application is using the accessibility API or not, but we also know precisely what kind of information it is asking for. While not all accessibility API calls are logged, this should still give us some interesting information!&lt;/p&gt;
&lt;h3 id=&quot;onscreen-keyboard&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/8/what-exactly-is-the-accessibility-api/#onscreen-keyboard&quot;&gt;&lt;span&gt;Onscreen Keyboard&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I was very surprised to see that the &lt;a href=&quot;https://learn.microsoft.com/en-us/windows/iot/iot-enterprise/os-features/on-screen-keyboard&quot;&gt;onscreen keyboard&lt;/a&gt; was making accessibility API calls to Chromium. I launched the onscreen keyboard and typed some random gibberish into google &lt;em&gt;(the &amp;quot;fdtgdgejcd/cgj&amp;quot; string to be precise)&lt;/em&gt; and got the following results.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_ACC_FOCUS:&lt;/strong&gt; 6 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_ACC_PARENT:&lt;/strong&gt; 10 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_ACC_STATE:&lt;/strong&gt; 7 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_UNIQUE_ID:&lt;/strong&gt; 8 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_WINDOW_HANDLE:&lt;/strong&gt; 8 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_IA2_GET_ATTRIBUTES:&lt;/strong&gt; 1 hit&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_QUERY_SERVICE:&lt;/strong&gt; 108 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_ROLE:&lt;/strong&gt; 4 hits&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;windows-magnifier&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/8/what-exactly-is-the-accessibility-api/#windows-magnifier&quot;&gt;&lt;span&gt;Windows Magnifier&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Magnification software also makes good use of accessibility APIs. In this workflow, I used the &lt;a href=&quot;https://support.microsoft.com/en-us/windows/use-magnifier-to-make-things-on-the-screen-easier-to-see-414948ba-8b1c-d3bd-8615-0e5e32204198&quot;&gt;Windows Magnifier&lt;/a&gt; and then launched Chromium to the &lt;a href=&quot;https://www.w3.org/TR/WCAG21/&quot;&gt;WCAG 2.1 guidelines&lt;/a&gt;. I then zoomed in to 200%, then zoomed back out to 100%. Here are the results:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_ACC_LOCATION:&lt;/strong&gt; 18 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_ACC_CHILD:&lt;/strong&gt; 41 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_ACC_FOCUS:&lt;/strong&gt; 37 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_ACC_NAME:&lt;/strong&gt; 2 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_ACC_PARENT:&lt;/strong&gt; 112 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_ACC_ROLE:&lt;/strong&gt; 25 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_ACC_STATE:&lt;/strong&gt; 101 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_UNIQUE_ID:&lt;/strong&gt; 186 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_WINDOW_HANDLE:&lt;/strong&gt; 23 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_IA2_GET_ATTRIBUTES:&lt;/strong&gt; 29 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_QUERY_SERVICE:&lt;/strong&gt; 708 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_ROLE:&lt;/strong&gt; 61 hits&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;power-automate&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/8/what-exactly-is-the-accessibility-api/#power-automate&quot;&gt;&lt;span&gt;Power Automate&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://powerautomate.microsoft.com/en-us/&quot;&gt;Power Automate&lt;/a&gt; is a tool that automates tasks in a UI. I have a simple workflow where I launch an instance of Chrome that navigates to a google search results page for &amp;quot;test&amp;quot;, then clicks on the first link in the results. We get the following hits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_ACC_PARENT:&lt;/strong&gt; 19 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_ACC_STATE:&lt;/strong&gt; 1 hit&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_UNIQUE_ID:&lt;/strong&gt; 4 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_IA2_GET_ATTRIBUTES:&lt;/strong&gt; 1 hit&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_QUERY_SERVICE:&lt;/strong&gt; 82 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_ROLE:&lt;/strong&gt; 1 hit&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;grammarly&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/8/what-exactly-is-the-accessibility-api/#grammarly&quot;&gt;&lt;span&gt;Grammarly&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.grammarly.com/?transaction_id=102fb088d4330b801810bcaf98b95d&amp;amp;affiliateNetwork=ho&amp;amp;affiliateID=124337&quot;&gt;Grammarly&lt;/a&gt; is a tool that attempts to improve your writing skills. The native application seems to have a natural usecase for using the accessibility API - we want to get text from some editable text area in an application, then programmatically insert some different text back if the user accepts Grammarly&#39;s suggestions.&lt;/p&gt;
&lt;p&gt;Note that in this test I explicitly used the native application version of Grammarly, not the browser extension. The browser extension will not need to use accessibility APIs since it can simply scrape the DOM.&lt;/p&gt;
&lt;p&gt;In this workflow, I launched &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea&quot;&gt;MDN&#39;s textarea article&lt;/a&gt; and typed in the word &amp;quot;salaid&amp;quot; into the provided &lt;code&gt;&amp;lt;textarea&amp;gt;&lt;/code&gt; element. I then waited for Grammarly to give me an autocorrect suggestion to &amp;quot;salad&amp;quot;, and accepted the suggestion. We get the following hits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_ACC_LOCATION:&lt;/strong&gt; 306 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_ADD_SELECTION:&lt;/strong&gt; 1 hit&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_ACC_CHILD:&lt;/strong&gt; 134 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_ACC_CHILD_COUNT:&lt;/strong&gt; 10 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_ACC_NAME:&lt;/strong&gt;  157 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_ACC_PARENT:&lt;/strong&gt; 871 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_ACC_ROLE:&lt;/strong&gt; 20 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_ACC_STATE:&lt;/strong&gt; 325 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_ACC_VALUE:&lt;/strong&gt; 50 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_CARET_OFFSET:&lt;/strong&gt; 12 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_CHARACTER_EXTENTS:&lt;/strong&gt; 64 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_INDEX_IN_PARENT:&lt;/strong&gt; 8 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_N_SELECTIONS:&lt;/strong&gt; 14 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_SELECTION:&lt;/strong&gt; 3 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_STATES:&lt;/strong&gt; 19 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_TEXT:&lt;/strong&gt; 34 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_TOOLKIT_NAME:&lt;/strong&gt; 22 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_UNIQUE_ID:&lt;/strong&gt; 408 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_GET_WINDOW_HANDLE:&lt;/strong&gt; 142 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_IA2_GET_ATTRIBUTES:&lt;/strong&gt; 364 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_QUERY_SERVICE:&lt;/strong&gt; 6411 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_ROLE:&lt;/strong&gt; 277 hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMA_API_SET_SELECTION:&lt;/strong&gt; 1 hit&lt;/li&gt;
&lt;/ul&gt;
&lt;details&gt;
&lt;summary&gt;On Grammarly&#39;s accessibility API usage&lt;/summary&gt;
&lt;p&gt;These results really surprised me - I didn&#39;t expect Grammarly to make such heavy use of these accessibility APIs. I even did this workflow 3 times to make sure I wasn&#39;t missing anything, and confirmed that before I launched Grammarly that the WinAPIs histogram had zero entries.
&lt;/p&gt;
&lt;p&gt;I wonder how many redundancies are here, although it&#39;s hard for me to say without knowing the reasons behind all of these API calls.&lt;/p&gt;
&lt;/details&gt;
&lt;h3 id=&quot;mobile-password-managers&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/8/what-exactly-is-the-accessibility-api/#mobile-password-managers&quot;&gt;&lt;span&gt;Mobile Password Managers&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;OK, I don&#39;t have data here since this is clearly not on Windows. However, notice how you can give accessibility permissions to password managers on Android, and that they can start overlaying their own UI on password fields after you do that. Visiting the &lt;a href=&quot;chrome://histograms/#Accessibility.Performance.HandleAXEvents&quot;&gt;histogram for HandleAXEvents&lt;/a&gt; on android Chromium does confirm that accessibility mode is turned on, although I can&#39;t comment on what API calls they are making.&lt;/p&gt;
&lt;h2 id=&quot;how-does-the-browser-generate-the-accessibility-tree&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/8/what-exactly-is-the-accessibility-api/#how-does-the-browser-generate-the-accessibility-tree&quot;&gt;&lt;span&gt;How does the browser generate the accessibility tree?&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Generating and updating an information dense structure like the accessibility tree in a performant way can be a very interesting technical challenge. This is even more true when the source of data comes from dynamic HTML and CSS, which can be combined in a variety of ways.&lt;/p&gt;
&lt;p&gt;While there are lots of things to keep in mind when generating the accessibility tree, we&#39;ll restrict our discussion to the basics: how do we generate the &lt;strong&gt;name&lt;/strong&gt; and &lt;strong&gt;role&lt;/strong&gt; for a given accessibility node?&lt;/p&gt;
&lt;h3 id=&quot;generating-the-name&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/8/what-exactly-is-the-accessibility-api/#generating-the-name&quot;&gt;&lt;span&gt;Generating the name&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Although I&#39;m simplifying a bit, there are three main ways a name can be generated for a node:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Name from content&lt;/li&gt;
&lt;li&gt;Name from labelling element&lt;/li&gt;
&lt;li&gt;Name from author&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Name from content&lt;/strong&gt; is a strategy where the name of a node is derived from its text content. For example, suppose we have the following markup:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;a&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/projects&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;See my projects&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For the link&#39;s accessibility node, browsers are smart enough to make the node&#39;s name be the same as the node&#39;s text content. This gives screen readers the appropriate name to read, and also allows voice recognition software to click on this link if the user requested it.&lt;/p&gt;
&lt;div class=&quot;ax-node&quot;&gt;
&lt;p&gt;link&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Name&lt;/dt&gt;
&lt;dd&gt;&quot;See my projects&quot;&lt;/dd&gt;
&lt;dt&gt;Role&lt;/dt&gt;
&lt;dd&gt;Link&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;
&lt;p&gt;Browsers adopt a similar strategy for something like a button:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;button&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Dark theme&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which would lead to generating an accessibility node that looks something like:&lt;/p&gt;
&lt;div class=&quot;ax-node&quot;&gt;
&lt;p&gt;button&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Name&lt;/dt&gt;
&lt;dd&gt;&quot;Dark theme&quot;&lt;/dd&gt;
&lt;dt&gt;Role&lt;/dt&gt;
&lt;dd&gt;Button&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;
&lt;p&gt;However, note that this strategy can&#39;t be implemented in a sensible way for all &lt;code&gt;HTMLElements&lt;/code&gt;. For example, could we generate a good name from content for even a simple table like the one below?&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;table&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;tr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;		&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;th&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Countries&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;th&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;		&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;th&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Capitals&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;th&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;		&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;th&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Population&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;th&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;		&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;th&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Language&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;th&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;tr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;tr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;		&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;td&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;USA&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;td&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;		&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;td&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Washington, D.C.&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;td&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;		&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;td&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;309 million&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;td&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;		&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;td&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;English&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;td&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;tr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;tr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;		&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;td&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Sweden&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;td&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;		&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;td&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Stockholm&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;td&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;		&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;td&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;9 million&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;td&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;		&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;td&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Swedish&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;td&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;tr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;table&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
  &lt;tr&gt;
    &lt;th&gt;Countries&lt;/th&gt;
    &lt;th&gt;Capitals&lt;/th&gt;
    &lt;th&gt;Population&lt;/th&gt;
    &lt;th&gt;Language&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;USA&lt;/td&gt;
    &lt;td&gt;Washington, D.C.&lt;/td&gt;
    &lt;td&gt;309 million&lt;/td&gt;
    &lt;td&gt;English&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Sweden&lt;/td&gt;
    &lt;td&gt;Stockholm&lt;/td&gt;
    &lt;td&gt;9 million&lt;/td&gt;
    &lt;td&gt;Swedish&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Name from labelling elements&lt;/strong&gt; is the second strategy browsers use to generate a name for an accessibility node. Certain &lt;code&gt;HTMLElements&lt;/code&gt; can source their name from a specific &lt;code&gt;HTMLElement&lt;/code&gt; that serves as a natural label.&lt;/p&gt;
&lt;p&gt;For example, going back to the table example from above, we can add a &lt;code&gt;&amp;lt;caption&amp;gt;&lt;/code&gt; element to source the name from.&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;table&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;caption&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;		Some title&lt;br /&gt;	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;caption&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;	...&lt;br /&gt;	&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Same table content as before --&gt;&lt;/span&gt;&lt;br /&gt;	...&lt;br /&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;table&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
  &lt;caption&gt;Some title&lt;/caption&gt;
  &lt;tr&gt;
    &lt;th&gt;Countries&lt;/th&gt;
    &lt;th&gt;Capitals&lt;/th&gt;
    &lt;th&gt;Population&lt;/th&gt;
    &lt;th&gt;Language&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;USA&lt;/td&gt;
    &lt;td&gt;Washington, D.C.&lt;/td&gt;
    &lt;td&gt;309 million&lt;/td&gt;
    &lt;td&gt;English&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Sweden&lt;/td&gt;
    &lt;td&gt;Stockholm&lt;/td&gt;
    &lt;td&gt;9 million&lt;/td&gt;
    &lt;td&gt;Swedish&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;The table can then have an accessibility node that looks something like this:&lt;/p&gt;
&lt;div class=&quot;ax-node&quot;&gt;
&lt;p&gt;table&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Name&lt;/dt&gt;
&lt;dd&gt;&quot;Some title&quot;&lt;/dd&gt;
&lt;dt&gt;Role&lt;/dt&gt;
&lt;dd&gt;Table&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;
&lt;p&gt;An even more natural example is the pairing of an &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; element.&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;label&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;input&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;  Some label&lt;br /&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;label&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;input&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;checkbox&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token attr-name&quot;&gt;&amp;lt;!--&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;Whatever&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;other&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;attributes&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;you&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;want&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;/&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which will generate an accessibility node that looks something like this:&lt;/p&gt;
&lt;div class=&quot;ax-node&quot;&gt;
&lt;p&gt;checkbox&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Name&lt;/dt&gt;
&lt;dd&gt;&quot;Some label&quot;&lt;/dd&gt;
&lt;dt&gt;Role&lt;/dt&gt;
&lt;dd&gt;Checkbox&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Name from author&lt;/strong&gt; is the third strategy browsers can use to generate a name. In this case, the browser relies on the web developer to manually supply an accessible name using the &lt;code&gt;aria-label&lt;/code&gt; or &lt;code&gt;aria-labelledby&lt;/code&gt; attributes. A name from author &lt;strong&gt;always&lt;/strong&gt; overrides other naming strategies - assuming that the role &lt;a href=&quot;https://w3c.github.io/aria/#namefromauthor&quot;&gt;supports name from author&lt;/a&gt;, anyway. For example, if we had some HTML as follows:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;a&lt;/span&gt;&lt;br /&gt;	&lt;span class=&quot;token attr-name&quot;&gt;aria-label&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;Not a chance!&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;	&lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/projects&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;	&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;See my projects&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;a&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;the accessibility node that is generated would have the name &amp;quot;Not a chance!&amp;quot;:&lt;/p&gt;
&lt;div class=&quot;ax-node&quot;&gt;
&lt;p&gt;link&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Name&lt;/dt&gt;
&lt;dd&gt;&quot;Not a chance!&quot;&lt;/dd&gt;
&lt;dt&gt;Role&lt;/dt&gt;
&lt;dd&gt;Link&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;
&lt;p&gt;Note that using ARIA in this case is extremely bad, as browsers already have a great name it can generate from content. Overriding the name in this way can also make it so voice recognition software won&#39;t be able to find the link if a user says &amp;quot;Click see my projects&amp;quot;, as this link has a completely different accessible name. See the &lt;a href=&quot;https://www.w3.org/WAI/WCAG21/Understanding/label-in-name.html&quot;&gt;Label in Name criterion&lt;/a&gt; for a related discussion.&lt;/p&gt;
&lt;div class=&quot;details-grouper&quot;&gt;
&lt;details&gt;
&lt;summary&gt;Musings on name from content&lt;/summary&gt;
&lt;P&gt;
Even though the ARIA spec says that elements with the &lt;code&gt;row&lt;/code&gt; role must compute their name from content, &lt;a href=&quot;https://github.com/chromium/chromium/blob/540343ddd9868d6a3b82ab7514a6d842e91120f2/third_party/blink/renderer/modules/accessibility/ax_object.cc#L7234&quot;&gt;Chromium only does this conditionally&lt;/a&gt; for performance purposes.
&lt;/P&gt;
&lt;P&gt;
&lt;a href=&quot;https://codepen.io/sivakusayan/pen/XWobyEJ&quot;&gt;This codepen for conditional row name computations&lt;/a&gt; allows you to play around with this behavior. I have only tested this in Chromium, but I haven&#39;t tested this behavior in other browsers to see if they also try to make similar optimizations.
&lt;/P&gt;
&lt;/details&gt;
&lt;details&gt;
&lt;summary&gt;Musings on CSS contributions to name&lt;/summary&gt;
&lt;p&gt;
Did you know that CSS pseudoelements can also contribute to the accessible name of an element? I suggest that you try the &lt;a href=&quot;https://codepen.io/sivakusayan/pen/KKbprEj&quot;&gt;CSS pseudoname contribution codepen&lt;/a&gt; and use the accessibility inspector of your choice to see for yourself. &lt;a href=&quot;https://www.w3.org/TR/accname-1.2/#step2F.ii&quot;&gt;This behavior is spec&#39;d out&lt;/a&gt;, so you should see this behavior in all major browsers.
&lt;/p&gt;
&lt;p&gt;
Interestingly, Chromium does some additional work to &lt;a href=&quot;https://github.com/chromium/chromium/blob/ac2ea7ef1724b3004bfe884f3d8c709450218f87/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc#L1194&quot;&gt;not expose CSS pseudocontent coming from the micro clearfix hack&lt;/a&gt; in the accessibility tree. I don&#39;t have the time to make a codepen to test this, along with seeing what other browsers do at this time. I&#39;ll probably make an edit when I do later, though. 🙂
&lt;/p&gt;
&lt;/details&gt;
&lt;/div&gt;
&lt;h3 id=&quot;generating-the-role&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/8/what-exactly-is-the-accessibility-api/#generating-the-role&quot;&gt;&lt;span&gt;Generating the role&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The role of an accessibility node is generally simple to calculate if it has a corresponding HTMLElement. We can first use the role given to us by the ARIA role attribute if it exists. Otherwise, we can just look at the HTML tagname.&lt;/p&gt;
&lt;p&gt;For example, consider the following HTML:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;This is some text&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;button&lt;/code&gt; element when translated would just have the button role. Assistive technology know that it can interact with this control as a button, and query for state relevant for buttons.&lt;/p&gt;
&lt;p&gt;However, if we added a &lt;code&gt;role&lt;/code&gt; attribute to it:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;role&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;link&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;This is some text&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then the &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; element would be translated into having the &lt;code&gt;link&lt;/code&gt; role.
Note that you should generally not do this - if you really need a &lt;code&gt;link&lt;/code&gt;, just use the &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; element.&lt;/p&gt;
&lt;p&gt;There are some amounts of complexity to consider though. For example, &lt;a href=&quot;https://www.w3.org/TR/html-aria/#docconformance&quot;&gt;not all ARIA roles are valid on all HTMLElements&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Second, browsers don&#39;t always respect the semantics coming from an HTMLElement, although this is restricted to &lt;code&gt;tables&lt;/code&gt; and &lt;code&gt;lists&lt;/code&gt; as far as I&#39;m aware:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;All major browsers implement interesting heuristics to &lt;a href=&quot;https://sayansivakumaran.com/posts/2023/6/browser-table-accessibility-remediation/&quot;&gt;determine if a table should be exposed as a table&lt;/a&gt;. This is done to compensate for bad HTML where the &lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt; element is used as a styling tool rather than to communicate table semantics.&lt;/li&gt;
&lt;li&gt;Safari specifically &lt;a href=&quot;https://twitter.com/cookiecrook/status/1337226933822603270&quot;&gt;attempts to do something similar for lists&lt;/a&gt;. Other browsers don&#39;t seem to implement similar heuristics.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;wrapup&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/8/what-exactly-is-the-accessibility-api/#wrapup&quot;&gt;&lt;span&gt;Wrapup&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you take nothing else, the accessibility API is an API that lets you programmatically read off and interact with an application.
When generating the accessibility API, the browser has to consider both HTML and CSS to generate the accessibility tree.&lt;/p&gt;
&lt;h2 id=&quot;edit-history&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/8/what-exactly-is-the-accessibility-api/#edit-history&quot;&gt;&lt;span&gt;Edit History&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;9/17/2023: Clarified that &lt;code&gt;aria-label&lt;/code&gt; only overrides the name on roles that support name from author. Per the spec, it should not do anything otherwise.&lt;/li&gt;
&lt;/ul&gt;
</description>
      <pubDate>Thu, 24 Aug 2023 00:00:00 +0000</pubDate>
      <dc:creator>Sayan Sivakumaran</dc:creator>
      <guid>https://sayansivakumaran.com/posts/2023/8/what-exactly-is-the-accessibility-api/</guid>
    </item>
    <item>
      <title>On anxiety and becoming a better software engineer</title>
      <link>https://sayansivakumaran.com/posts/2023/7/on-becoming-a-better-software-engineer/</link>
      <description>&lt;p&gt;&lt;b&gt;FYI, this is a somewhat unintelligible stream of thoughts that have been bothering me over the past year.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;I&#39;ve recently been thinking a lot about whether I am a &amp;quot;good&amp;quot; or &amp;quot;bad&amp;quot; developer, to the point where it was probably a bit unhealthy. Ever since I started contributing to open source and doing things that are traditionally associated with &amp;quot;hacker culture&amp;quot;, I&#39;ve started to realize how much there is to know.&lt;/p&gt;
&lt;p&gt;This is something that &lt;em&gt;every&lt;/em&gt; long-time developer says, but I think this is one of those things that you don&#39;t truly understand until you come to that conclusion through your own experiences, instead of someone else&#39;s.&lt;/p&gt;
&lt;h2 id=&quot;there-is-a-plethora-of-talent-out-there&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/7/on-becoming-a-better-software-engineer/#there-is-a-plethora-of-talent-out-there&quot;&gt;&lt;span&gt;There is a plethora of talent out there.&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The more you immerse yourself in developer culture, the more you realize just how much talent there is in this space.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;There are developers that have been coding since they were in middle school, high school, or similar.&lt;/li&gt;
&lt;li&gt;There are developers that formally studied computer science in top-tier colleges and have done cool professional work, whether that be through internships or research or similar.&lt;/li&gt;
&lt;li&gt;There are developers with amazing design skills that make breathtakingly beautiful and usable software, all without the help of a UX designer.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I could go on. A lot of these developers don&#39;t realize how strong they are, because what they know is so normal to them.&lt;/p&gt;
&lt;p&gt;In comparison:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I only started to learn how to program in my senior year of college, mostly teaching myself with Udemy courses.&lt;/li&gt;
&lt;li&gt;I have a mathematics degree from an average college instead of a computer science degree. I did not have cool opportunities to apply my knowledge.&lt;/li&gt;
&lt;li&gt;I don&#39;t have great design skills (there is a reason why I made my website so minimal).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It&#39;s only recently I&#39;ve started recognizing the gaps I have when compared to people in the former group.&lt;/p&gt;
&lt;h2 id=&quot;self-taught-developers-later-in-life-tend-to-be-at-a-disadvantage&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/7/on-becoming-a-better-software-engineer/#self-taught-developers-later-in-life-tend-to-be-at-a-disadvantage&quot;&gt;&lt;span&gt;Self taught developers later in life tend to be at a disadvantage.&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There seems to be a growing pattern of people saying that you don&#39;t need a degree to be a developer. I agree with this to a point - anything you can learn in college you can learn on your own with enough effort.&lt;/p&gt;
&lt;p&gt;However, there is a practicality aspect to this. If you&#39;re learning how to code after college, you don&#39;t have as much free time as you might have had when you were younger. Depending on what kind of programming you want to do, the amount of investment you need to put in can go from approachable to absolutely intimidating.&lt;/p&gt;
&lt;p&gt;If you primarily code with &lt;a href=&quot;https://learn.microsoft.com/en-us/dotnet/standard/managed-code&quot;&gt;managed languages&lt;/a&gt;, I think this becomes much easier. There are a plenty of Udemy courses and Medium articles which will teach you to, at the very least, be a decent developer with those tools. You don&#39;t need to have indepth knowledge of how a computer works under the hood in order to do cool things, or know anything fancy that a computer science student might study. There are abstractions in place that will make sure you don&#39;t have to think about what&#39;s truly going on behind the scenes.&lt;/p&gt;
&lt;p&gt;If you start to do work with unmanaged code, however, the amount of knowledge you need to not shoot yourself in the foot goes up exponentially. For example, I wish that I:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Had a better knowledge of the kinds of things computers do under the hood.&lt;/li&gt;
&lt;li&gt;Had a better knowledge of how compilers work.&lt;/li&gt;
&lt;li&gt;Had a better knowledge of assembly code so I could see what the disassembly of my code does.&lt;/li&gt;
&lt;li&gt;Had a better knowledge of how to leverage the advantages I get with lower-level languages that I can&#39;t get with a higher-level language.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Among many other things. There aren&#39;t pretty and easily digestible Udemy courses or Medium articles for topics like this, at least for anything that is non-trivial, which is understandable as this knowledge tends to be more academic.&lt;/p&gt;
&lt;p&gt;I especially feel these pain points since I&#39;ve started contributing to Chromium - I&#39;ve never thought about the performance and memory implications of the code I write so much before, even for the easiest of fixes. While I think I&#39;m doing OK so far, it&#39;s definitely very intimidating for me.&lt;/p&gt;
&lt;h2 id=&quot;its-ok-to-take-your-time&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/7/on-becoming-a-better-software-engineer/#its-ok-to-take-your-time&quot;&gt;&lt;span&gt;It&#39;s ok to take your time.&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The thoughts that I&#39;ve listed above made me feel like I needed to rush to &amp;quot;catch up&amp;quot; with my peers. I wanted to obtain the knowledge that I missed out on so I can do the type of work I want to do. This has caused a lot of stress for me in the past year or so.&lt;/p&gt;
&lt;p&gt;Reading the article &lt;a href=&quot;https://norvig.com/21-days.html&quot;&gt;Teach Yourself Programming in Ten Years&lt;/a&gt; has helped me come to terms with the fact that it will take a long time for me to get to a place I am happy with, and that&#39;s okay. There&#39;s no need to be in a race with anyone, and there will always be someone that is smarter than you anyway.&lt;/p&gt;
&lt;p&gt;It&#39;s not realistic to expect yourself to be a very good engineer within 2 or 3 years. As long as I move slowly towards my goal, that is enough for me.&lt;/p&gt;
&lt;h2 id=&quot;its-ok-to-make-mistakes&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/7/on-becoming-a-better-software-engineer/#its-ok-to-make-mistakes&quot;&gt;&lt;span&gt;It&#39;s ok to make mistakes.&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I&#39;m a perfectionist, which isn&#39;t always a good thing. It means that I sometimes move slower than necessary, and also means that I can beat myself up pretty hard whenever I make a mistake.&lt;/p&gt;
&lt;p&gt;Since we&#39;re human, we&#39;re naturally going to have buggy code. We can invest in tooling that can minimize these bugs, but bugs are just a fact of life. When we make a mistake, the most we can do is figure out why that bug was let through, fix it, and make sure tests are in place so that the bug doesn&#39;t appear again. Maybe hold a post-mortem if the bug was extremely bad, too.&lt;/p&gt;
&lt;p&gt;I know that I&#39;ve made my share of mistakes. My most recent one came from my implementation of enabling &lt;code&gt;aria-errormessage&lt;/code&gt; to point to multiple &lt;code&gt;HTMLElements&lt;/code&gt;. The crux of the Windows-only bug is that the order that accessibility nodes are returned in the accessibility API isn&#39;t always the same as the order specified in the HTML. In fact, this is true for all ARIA attributes that point to multiple HTMLElements except &lt;code&gt;aria-labelledby&lt;/code&gt; and &lt;code&gt;aria-describedby&lt;/code&gt; &lt;em&gt;(if you&#39;re curious, the array we return is sorted by when we created the accessibility node)&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;I&#39;m still not sure how I didn&#39;t catch it while I was testing, given that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I&#39;m an extremely paranoid person and look at my patches with a lot of scrutiny out of fear of breaking something.&lt;/li&gt;
&lt;li&gt;I updated a fair amount of integration tests, added new integration tests, and even improved the &lt;a href=&quot;https://chromium.googlesource.com/chromium/src/+/HEAD/content/test/data/accessibility/readme.md&quot;&gt;dump tree testing&lt;/a&gt; code to make it more airtight when it comes to changes like this.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thankfully, this bug shouldn&#39;t be breaking anything since:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The code I submitted is implementing a new feature of ARIA, so websites shouldn&#39;t be using it in production right now.&lt;/li&gt;
&lt;li&gt;At most, it causes error messages to be read in the wrong order, which while confusing &lt;em&gt;probably&lt;/em&gt; isn&#39;t a blocker.&lt;/li&gt;
&lt;li&gt;I caught it in Chrome Canary.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Oh well, I released a buggy implementation - I&#39;ll commit a fix for it and learn from this.&lt;/p&gt;
&lt;p&gt;This likely won&#39;t be the last time I release buggy code. Even the most talented software engineers can write buggy code at times &lt;em&gt;(even if they write less bugs than other developers)&lt;/em&gt;! As long as I learn from my mistakes and put in the necessary tests/tools to make sure it doesn&#39;t happen again, I think I&#39;ll be able to live with myself.&lt;/p&gt;
&lt;p&gt;It&#39;s part of being human.&lt;/p&gt;
&lt;h2 id=&quot;you-dont-have-to-be-the-best&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/7/on-becoming-a-better-software-engineer/#you-dont-have-to-be-the-best&quot;&gt;&lt;span&gt;You don&#39;t have to be the best.&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This might be obvious to most of you, but as someone who grew up as &lt;a href=&quot;https://www.mindbodygreen.com/articles/golden-child-syndrome&quot;&gt;the golden child&lt;/a&gt; in an Asian household, this took a long time for me to accept. I&#39;m still working on accepting this now.&lt;/p&gt;
&lt;p&gt;I do development because I enjoy making software that improves peoples&#39; lives. It&#39;s a big reason why I got into accessibility.
I don&#39;t need to be the best engineer in my field, or even on my team, to do that. I don&#39;t need to be the best engineer to lead a happy life - there are other things that can do that for me, like friends and family.&lt;/p&gt;
&lt;p&gt;For me, I want to be better because that will reflect in better software for the people who need it. It doesn&#39;t matter if someone else is better than me as long as I&#39;m slightly better than I was yesterday.&lt;/p&gt;
&lt;p&gt;Most importantly, I think that being average isn&#39;t a bad thing. Being average is underrated, I think. Maybe the secret to happiness is not tying so much of your self worth with your career.&lt;/p&gt;
&lt;h2 id=&quot;helpful-resources&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/7/on-becoming-a-better-software-engineer/#helpful-resources&quot;&gt;&lt;span&gt;Helpful resources&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Some resources I found helpful while thinking through all of this for the past few months.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=-Afvtij-o2w&amp;t=0s&amp;ab_channel=bigboxSWE&quot;&gt; Software Engineering Anxiety&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://norvig.com/21-days.html&quot;&gt;Teach Yourself Programming in Ten Years&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://daedtech.com/how-developers-stop-learning-rise-of-the-expert-beginner/&quot;&gt;How developers stop learning: Rise of the expert beginner&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I especially appreciate my friends who put up with me ranting about how I feel like a bad engineer. I&#39;m happy and really lucky that I have wonderful friends like you all 🙂.&lt;/p&gt;
&lt;p&gt;If you don&#39;t have friends that you can rant about this to, I hope that you can, at the very least, tell yourself the same things I told myself in this post. Even if not now, eventually.&lt;/p&gt;
</description>
      <pubDate>Mon, 24 Jul 2023 00:00:00 +0000</pubDate>
      <dc:creator>Sayan Sivakumaran</dc:creator>
      <guid>https://sayansivakumaran.com/posts/2023/7/on-becoming-a-better-software-engineer/</guid>
    </item>
    <item>
      <title>Exploring the &quot;Is this a real or fake table?&quot; algorithm in desktop browsers</title>
      <link>https://sayansivakumaran.com/posts/2023/6/browser-table-accessibility-remediation/</link>
      <description>&lt;p&gt;There are a lot of websites out there that, unfortunately, use the &lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt; HTML element as a styling tool. This poses a problem to users of assistive technology, as there is now a lot of incorrect semantic information in the page.&lt;/p&gt;
&lt;p&gt;To mitigate this issue when creating the accessibility tree, browsers try to guess when a &lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt; is being used for purely styling purposes. If they guess that a &lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt; might not &lt;em&gt;really&lt;/em&gt; be a table, that information is then hinted to assistive technology. For example, &lt;a href=&quot;https://codepen.io/sivakusayan/pen/qBQBPmJ&quot;&gt;here is a &lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt;&lt;/a&gt; that no major browser on desktop will expose as a table - you can take any screen reader to the linked codepen to verify for yourself.&lt;/p&gt;
&lt;p&gt;I thought it would be interesting to look at this guessing algorithm in more detail. We will look at some minimal codepens of &lt;code&gt;&amp;lt;tables&amp;gt;&lt;/code&gt; that start out as purely stylistic layout tables, and then tweak them &lt;em&gt;just barely enough&lt;/em&gt; to make browsers think they are real data tables. 🙂&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;Definitions&lt;/summary&gt;
&lt;dl&gt;
&lt;dt id=&quot;accessibility-tree&quot;&gt;Accessibility tree&lt;/dt&gt;
&lt;dd&gt;A tree data structure that represents a graphical user interface, commonly consumed by assistive technology (although they are not the only consumers).&lt;/dd&gt;
&lt;dt id=&quot;assistive-technology&quot;&gt;Assistive technology&lt;/dt&gt;
&lt;dd&gt;Software or hardware that disabled people use to improve their quality of life.&lt;/dd&gt;
&lt;dt id=&quot;layout-table&quot;&gt;Layout table&lt;/dt&gt;
&lt;dd&gt;A table that is only used for styling, and not for showing tabular data.&lt;/dd&gt;
&lt;dt id=&quot;data-table&quot;&gt;Data table&lt;/dt&gt;
&lt;dd&gt;Any table that isn&#39;t a layout table.&lt;/dd&gt;
&lt;/dl&gt;
&lt;/details&gt;
&lt;h2 id=&quot;notes-on-testing&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/6/browser-table-accessibility-remediation/#notes-on-testing&quot;&gt;&lt;span&gt;Notes on testing&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Only if you want to know the gritty technical details.&lt;/p&gt;
&lt;div class=&quot;details-grouper&quot;&gt;
&lt;details&gt;
    &lt;summary&gt;A note on how I tested&lt;/summary&gt;
    As this article is only concerned with how browsers expose tables in the desktop accessibility APIs, here is how I get my results for each browser:
&lt;ul&gt;
&lt;li&gt;On Windows, I will look for the &lt;code&gt;layout-guess&lt;/code&gt; attribute on the &lt;code&gt;&amp;lt;table&#39;s&amp;gt;&lt;/code&gt; IAccessible2 node using the &lt;a href=&quot;https://chromium.googlesource.com/chromium/src/+/master/tools/accessibility/inspect/README.md&quot;&gt;dump tree utility&lt;/a&gt;. If a node has this attribute set to true, it&#39;s a layout table, otherwise it&#39;s a data table.&lt;/li&gt;
&lt;li&gt;On Mac, I will look to see if the &lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt; is exposed as a table in the accessibility tree using the &lt;a href=&quot;https://developer.apple.com/library/archive/documentation/Accessibility/Conceptual/AccessibilityMacOSX/OSXAXTestingApps.html&quot;&gt;Accessibility Inspector&lt;/a&gt;. If it&#39;s not, it&#39;s a layout table, otherwise it&#39;s a data table.&lt;/li&gt;
&lt;li&gt;On Linux:
&lt;ul&gt;
&lt;li&gt;For Chrome and Edge, I will look to see if the &lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt; is exposed as a table in the accessibility tree using the &lt;a href=&quot;https://chromium.googlesource.com/chromium/src/+/master/tools/accessibility/inspect/README.md&quot;&gt;dump tree utility&lt;/a&gt;. If it&#39;s not, it&#39;s a layout table, otherwise it&#39;s a data table.&lt;/li&gt;
&lt;li&gt;For Firefox, I will look for the &lt;code&gt;layout-guess&lt;/code&gt; attribute on the &lt;code&gt;&amp;lt;table&#39;s&amp;gt;&lt;/code&gt; &lt;abbr title=&quot;Assistive Technology - Service Provider Interface&quot;&gt;AT-SPI&lt;/abbr&gt; node using &lt;a href=&quot;https://help.gnome.org/users/accerciser/stable/introduction.html.en&quot;&gt;Accerciser&lt;/a&gt;. If a node has this attribute set to true, it&#39;s a layout table, otherwise it&#39;s a data table.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At the time of this writing, I am testing with versions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Chrome Version 114.0.5735.90&lt;/li&gt;
&lt;li&gt;Edge Version 114.0.1823.37&lt;/li&gt;
&lt;li&gt;Firefox Version 113.0.2&lt;/li&gt;
&lt;li&gt;Safari Version 16.4 (18615.1.26.11.23)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Finally, for simplicity&#39;s sake, I will not list browser + platform combinations as each individual browser&#39;s results don&#39;t seem to change with the desktop platform. I will just list the results of each browser, and you can assume those results are true for Windows, Mac, and Linux.&lt;/p&gt;
&lt;/details&gt;
&lt;details&gt;
&lt;summary&gt;A note if you want to test&lt;/summary&gt;
If you don&#39;t want to verify these results in the same way I did, here are some shortcuts you can use, which aren&#39;t as rigorous, but can give you a basic way of verifying what I&#39;m saying:
&lt;ul&gt;
&lt;li&gt;On Chrome and Edge, you can use the &lt;a href=&quot;https://developer.chrome.com/docs/devtools/accessibility/reference/#pane&quot;&gt;Accessibility Inspector&lt;/a&gt; in the developer tools. Layout tables will be explicitly called out as layout tables here.&lt;/li&gt;
&lt;li&gt;On Firefox, you can use:
&lt;ul&gt;
&lt;li&gt;NVDA on Windows and use &lt;a href=&quot;https://dequeuniversity.com/screenreaders/nvda-keyboard-shortcuts#nvda-tables&quot;&gt;NVDA table shortcuts&lt;/a&gt; to see if it detects a table.&lt;/li&gt;
&lt;li&gt;Voiceover on Mac and use &lt;a href=&quot;https://dequeuniversity.com/screenreaders/voiceover-keyboard-shortcuts#vo-mac-tables&quot;&gt;Voiceover table shortcuts&lt;/a&gt; to see if it detects a table.&lt;/li&gt;
&lt;li&gt;Orca on Linux and use &lt;a href=&quot;https://help.gnome.org/users/orca/stable/commands_structural_navigation.html.en#tables&quot;&gt;Orca table shortcuts&lt;/a&gt; to see if it detects a table.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;On Safari, you can use Voiceover and use &lt;a href=&quot;https://dequeuniversity.com/screenreaders/voiceover-keyboard-shortcuts#vo-mac-tables&quot;&gt;Voiceover table shortcuts&lt;/a&gt; to see if it detects a table.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Finally, if you plan on modifying the HTML to experiment, you should use the CodePen editor instead of modifying the HTML directly through the developer tools.&lt;/p&gt;
&lt;p&gt;I&#39;m seeing that browsers don&#39;t necessarily update the guess of whether a table is a layout table or a data table if the table is modified after being rendered, so edits through the developer tools won&#39;t always work. Edits in the codepen work as they refresh the embedded &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/details&gt;
&lt;/div&gt;
&lt;h2 id=&quot;determining-table-ness-via-html&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/6/browser-table-accessibility-remediation/#determining-table-ness-via-html&quot;&gt;&lt;span&gt;Determining table-ness via HTML&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;All major browsers will attempt to search for certain table-specific semantic elements. If it finds any, it will abort the algorithm early and just declare the table to be a data table. Browsers seem to agree that tables with a &lt;code&gt;&amp;lt;caption&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;thead&amp;gt;&lt;/code&gt;, or &lt;code&gt;&amp;lt;tfoot&amp;gt;&lt;/code&gt; are all data tables.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://codepen.io/sivakusayan/pen/LYgozwL&quot;&gt;Codepen: Determining table-ness via the presence of HTML elements&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;determining-table-ness-via-the-number-of-rows&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/6/browser-table-accessibility-remediation/#determining-table-ness-via-the-number-of-rows&quot;&gt;&lt;span&gt;Determining table-ness via the number of rows&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;All major browsers will attempt to count the number of rows that a table has, and if it has sufficiently many it will be declared a data table. Chrome, Edge, Firefox, and Safari all agree that a table with at least 20 rows is a data table.&lt;/p&gt;
&lt;p&gt;As soon as we make the table have 19 rows, however, every browser except Firefox considers the table a layout table.&lt;/p&gt;
&lt;details&gt;
    &lt;summary&gt;Thoughts on Firefox behavior&lt;/summary&gt;
    &lt;p&gt;
    I was a little bit confused at first on why Firefox thought the extremely minimal table with 19 rows was a data table. Especially since Firefox seems to do a similar row count check that other browsers use, from reading the code. 
    &lt;/p&gt;
    &lt;p&gt;
    My immediate guess as to why (without examining with a debugger) is that Firefox seems to assume every table is a data table until proven otherwise, while other browsers assume that a table is a layout table until proven otherwise. Again, this is just speculation from reading the code, and I would need to use a debugger to verify my hypothesis.
    &lt;/p&gt;
&lt;/details&gt;
&lt;p&gt;&lt;a href=&quot;https://codepen.io/sivakusayan/pen/KKGLXjj&quot;&gt;Codepen: Determining table-ness via the number of rows&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;determining-table-ness-via-the-css-background-color-of-table-rows&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/6/browser-table-accessibility-remediation/#determining-table-ness-via-the-css-background-color-of-table-rows&quot;&gt;&lt;span&gt;Determining table-ness via the CSS &lt;code&gt;background-color&lt;/code&gt; of table rows&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The incorporation of CSS in this guessing algorithm is very interesting to me.&lt;/p&gt;
&lt;p&gt;All four browsers seem to agree that a table with alternating &lt;code&gt;background-colors&lt;/code&gt; on its rows is a data table, as long as the table has more than two rows. Firefox is the only browser that does not enforce a minimum of three rows when checking that the rows have alternating backgrounds.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://codepen.io/sivakusayan/pen/jOeoGoo&quot;&gt;Codepen: Determining table-ness via the CSS background-color of table rows&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;determining-table-ness-via-the-css-background-color-of-table-cells&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/6/browser-table-accessibility-remediation/#determining-table-ness-via-the-css-background-color-of-table-cells&quot;&gt;&lt;span&gt;Determining table-ness via the CSS &lt;code&gt;background-color&lt;/code&gt; of table cells&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Chrome, Edge, and Safari all check if any kind of &lt;code&gt;background-color&lt;/code&gt; CSS property is defined on the table cell. If this is true for at least half of the cells in the table, then it becomes a data table. However, note that the &lt;code&gt;background-color&lt;/code&gt; has to be explicitly defined on the &lt;code&gt;&amp;lt;td&amp;gt;&lt;/code&gt; - defining the &lt;code&gt;background-color&lt;/code&gt; on the &lt;code&gt;&amp;lt;tr&amp;gt;&lt;/code&gt; won&#39;t work.&lt;/p&gt;
&lt;p&gt;Firefox does not seem to employ this heuristic at all.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://codepen.io/sivakusayan/pen/YzJbrmY&quot;&gt;Codepen: Determining table-ness via the CSS background-color of table cells&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;determining-table-ness-via-the-css-border-of-table-cells&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/6/browser-table-accessibility-remediation/#determining-table-ness-via-the-css-border-of-table-cells&quot;&gt;&lt;span&gt;Determining table-ness via the CSS &lt;code&gt;border&lt;/code&gt; of table cells&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;All major browsers do checks on the border of table cells to help determine whether something is a data table or not.&lt;/p&gt;
&lt;p&gt;Chrome, Edge, and Safari check to see if &lt;em&gt;any&lt;/em&gt; side of the table cell has a border. If this is true for at least half of the cells in the table, those browsers expose the table as a data table.&lt;/p&gt;
&lt;p&gt;Firefox does it slightly differently - it only checks the first table cell, and checks if it has a border on &lt;em&gt;all&lt;/em&gt; sides. If so, Firefox exposes the table as a data table.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://codepen.io/sivakusayan/pen/wvYbrVR&quot;&gt;Codepen: Determining table-ness via the CSS border of table cells&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;source-code&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://sayansivakumaran.com/posts/2023/6/browser-table-accessibility-remediation/#source-code&quot;&gt;&lt;span&gt;Source code&lt;/span&gt;&lt;span class=&quot;anchor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Reading the source code for this algorithm was really helpful in constructing these minimal codepens.&lt;/p&gt;
&lt;p&gt;If you&#39;re curious, here is where you can walk through the algorithm&#39;s logic yourself in Chromium.
Note how you can opt out of this entire guessing logic by just manually setting &lt;code&gt;role=&amp;quot;table&amp;quot;&lt;/code&gt; on the element. (Of course, &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA&quot;&gt;don&#39;t use ARIA unless you need to&lt;/a&gt;)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/modules/accessibility/ax_layout_object.cc;drc=99f969b129a7123125ac7af40afb24277dd4767a;l=1043&quot;&gt;Chromium&#39;s layout table guess&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;details&gt;
&lt;summary&gt;If you can&#39;t access Chromium code search&lt;/summary&gt;
I&#39;ve been told by some users that the Chromium code search isn&#39;t accessible 🙁. While not ideal, I hope this &lt;a href=&quot;https://sayansivakumaran.com/posts/resources/chromiumTableLayoutGuess.txt&quot;&gt;raw text version of the code&lt;/a&gt; can be a temporary workaround.
&lt;/details&gt;
&lt;p&gt;As for the other browsers, I&#39;m not exactly sure where the logic is since I haven&#39;t debugged those browsers and am not as familiar with their codebases, but I can give a fairly likely guess from reading the code:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://searchfox.org/mozilla-central/rev/0c2945ad4769e2d4428c72e6ddd78d60eb920394/accessible/generic/TableAccessible.cpp#19&quot;&gt;Probably Firefox&#39;s layout table guess&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/WebKit/WebKit/blob/023f54b8e5b80830c6d4eee7f54143aa4d15b9b9/Source/WebCore/accessibility/AccessibilityTable.cpp#L114&quot;&gt;Probably Safari&#39;s layout table guess&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There is some logic I didn&#39;t cover - for example, Firefox seems to do checks on how wide the &lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt; is relative to the entire page. I also left out mobile platforms in order to simplify this post, as the mobile behavior doesn&#39;t seem as consistent at an initial glance and would require some nuance. I encourage you to read the code yourself if you want to learn more!&lt;/p&gt;
&lt;p&gt;Finally, here is some more code speculation/archaeology that I did while doing research for this post:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/search?q=repo%3Anvaccess%2Fnvda%20layout-guess&amp;amp;type=code&quot;&gt;Probably where NVDA checks to see if a table is a layout table or a data table&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gitlab.gnome.org/search?search=%27layout-guess%27&amp;amp;nav_source=navbar&amp;amp;project_id=1911&amp;amp;group_id=8&amp;amp;search_code=true&amp;amp;repository_ref=master&quot;&gt;Probably where Orca checks to see if a table is a layout table or a data table&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Again, there might be some context I&#39;m missing, but I think it&#39;s cool to see how everything connects together.&lt;/p&gt;
</description>
      <pubDate>Tue, 06 Jun 2023 00:00:00 +0000</pubDate>
      <dc:creator>Sayan Sivakumaran</dc:creator>
      <guid>https://sayansivakumaran.com/posts/2023/6/browser-table-accessibility-remediation/</guid>
    </item>
  </channel>
</rss>