rndthts.dev https://rndthts.dev/ Recent content on rndthts.dev Hugo -- gohugo.io en-us Wed, 22 Jan 2025 21:40:37 +0100 From 'I Just Want a Piggy Bank' to a CNC-Ready Matrix Generator https://rndthts.dev/posts/from-piggy-bank-to-cnc-matrix-generator/ Sun, 08 Mar 2026 12:30:00 +0100 https://rndthts.dev/posts/from-piggy-bank-to-cnc-matrix-generator/ <p>Most of what I write about here is software development. But in my free time, I also like to mess around with a CO2 laser CNC machine.</p> <p>Recently I wanted to build a piggy bank (saving box) where you track progress by crossing out a number grid until you hit a target amount.</p> <h2 id="the-problem-templates-exist-until-they-dont">The Problem: Templates Exist Until They Don&rsquo;t</h2> <p>Online templates work only for common totals. As soon as you need custom values, they break down:</p> <ul> <li>You want a custom target (for example: 750, 1350, 4200)</li> <li>You want your own grid size (rows and columns based on your physical design)</li> <li>You want specific denominations (for example: 1, 2, 5, 10, 20, 50, 100)</li> </ul> <p>As software engineers, we usually do not stop at &ldquo;close enough.&rdquo; We build what we actually need.</p> <h2 id="what-i-built-piggy-bank-matrix-builder">What I Built: Piggy Bank Matrix Builder</h2> <p><a href="https://rndthts.dev/tools/piggy-bank-matrix/"><strong>Piggy Bank Matrix Builder</strong></a> generates a CNC-ready SVG matrix using your target sum, chosen numbers, and grid size.</p> <h2 id="what-it-does">What It Does</h2> <ul> <li>Set a target sum</li> <li>Provide numbers (comma-separated) as denominations or any custom values</li> <li>Choose rows and columns</li> <li>Adjust a small-number bias to influence distribution</li> <li>Export as: <ul> <li>SVG (for laser/CNC)</li> <li>CSV (for further edits)</li> </ul> </li> </ul> <h2 id="why-this-was-a-good-fit-for-vibe-coding">Why This Was a Good Fit for Vibe Coding</h2> <p>This was a perfect vibe coding project for me:</p> <ul> <li>Performance is not a hard requirement</li> <li>The software is not safety-critical</li> <li>I do not usually write in this language stack</li> <li>I can verify results quickly by checking totals, previewing SVG, and testing on real material</li> </ul> <p>That makes AI-assisted iteration fast and practical, with clear validation at each step.</p> <h2 id="video-version">Video Version</h2> <p><a href="https://www.youtube.com/watch?v=h-mbZj34kWo"><strong>From Idea to Working Tool With Codex: Target Piggy Banks</strong></a></p> <h2 id="try-it">Try It</h2> <p>If you build something with it (different currencies, weird denominations, alternative layouts), I would love to see it.</p> <p>Tool: <a href="https://rndthts.dev/tools/piggy-bank-matrix/">https://rndthts.dev/tools/piggy-bank-matrix/</a></p> Building a YouTube Channel in Public https://rndthts.dev/posts/building-in-public/ Wed, 25 Feb 2026 10:00:00 -0500 https://rndthts.dev/posts/building-in-public/ <h2 id="bootstrapping-a-youtube-channel-with-code">Bootstrapping a YouTube Channel With Code</h2> <p>I decided to start a YouTube channel around one simple idea:</p> <p><strong>What is actually possible with code?</strong></p> <p>This project is mostly for fun. I want to explore YouTube as a platform and experiment with areas of coding I haven’t touched before. Instead of overthinking it, I’m learning by building in public.</p> <p>And the first thing I’m building is the tooling for the channel itself.</p> <h2 id="building-the-tools-first">Building the Tools First</h2> <p>The first series is focused entirely on bootstrapping the channel.</p> <p>Instead of manually recording and editing everything, I’m creating small tools that help me produce better videos. I build the tools, use them to create videos, then improve them as I go.</p> <p>Over time, I plan to make these tools available to others.</p> <p>I’m also delegating as much of the coding as possible to AI tools. Part of this journey is exploring how far AI-assisted development can go, and where it still needs human input.</p> <h3 id="the-first-attempt">The First Attempt</h3> <p>I wanted to create a welcome video with a clean terminal-style look.</p> <p>So I opened <code>iTerm</code> and recorded myself typing the text.</p> <p>It looked… bad. Everything was off. The typing felt awkward. It wasn’t what I had imagined.</p> <p>Here’s that first version:</p> <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"> <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/t4PPIEStaNU?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe> </div> <p>Instead of trying to fix the recording setup, I decided to build something better.</p> <h3 id="a-simple-terminal-typer-app">A Simple Terminal Typer App</h3> <p>I wrote a small terminal-typer app that simulates typing and exports directly to video.</p> <p>That way I can:</p> <ul> <li>Control timing</li> <li>Replay scripts consistently</li> <li>Generate clean output every time</li> </ul> <p>Here’s how it looks like:</p> <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"> <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/A3s_dYqoGqg?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe> </div> <p>Using it, I recreated the welcome video, and it turned out much closer to what I originally wanted.</p> <p>Here is the current version of the welcome video:</p> <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"> <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/vYnN9xU77no?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe> </div> <p><strong>This is just the beginning.</strong></p> <p>Right now, I’m focused on building the foundation.</p> <p>If you’d like to follow the journey, consider <strong><a href="https://www.youtube.com/@rndthts">subscribing</a></strong> And if there’s something you’d like to see me build, let me know.</p> <p>If you watched the videos, you’ll notice they’re still silent. Adding audio is one of the next steps in this experiment.</p> Non-Technical Books For Developers https://rndthts.dev/posts/non-tech-dev-books/ Mon, 24 Feb 2025 00:40:39 +0100 https://rndthts.dev/posts/non-tech-dev-books/ <p>Mostly, I will write about the technical aspects of software development, but before I continue with that, I want to list some books that, in my opinion , every developer should read. Those books aren’t directly related to technical topics. This list is based on books I have read, and it just so happens that there are 10 of them. <strong>I didn’t chase that number.</strong></p> <p>Since it’s still early in the year, you can still adjust your New Year’s resolutions and maybe even swap out some books on your reading list for some from the list below.</p> <p>I’ll write something about each book as a description, highlight, or opinion. So let’s start:</p> <h3 id="1-who-moved-my-cheese-by-spencer-johnson">1. Who Moved My Cheese? by Spencer Johnson</h3> <div class="image-container"> <p><img src="https://rndthts.dev/images/books/who_moved_my_cheese.jpg" alt="Who Moved My Cheese?"></p> </div> An easy read, I listed it first because it’s about change, something especially relevant in today’s AI boom. As developers, we should embrace AI as just another tool and use it to our advantage. <h3 id="2-never-split-the-difference-by-chris-voss">2. Never Split the Difference by Chris Voss</h3> <div class="image-container"> <p><img src="https://rndthts.dev/images/books/never_split.jpg" alt="Never Split the Difference"></p> </div> From what I’ve seen so far, the majority of developers struggle with negotiations. We’re often afraid to even consider it, whether it’s about salary, perks, project choices, technology, or even getting more CI machines. That’s why this book is such a valuable read. <h3 id="3-how-to-win-friends-and-influence-people-by-dale-carnegie">3. How to Win Friends and Influence People by Dale Carnegie</h3> <div class="image-container"> <p><img src="https://rndthts.dev/images/books/how_to_win_fr.jpg" alt="How to Win Friends and Influence People"></p> </div> Communication is an underrated skill for developers, and this classic teaches how to work effectively with people. <h3 id="4-the-mythical-man-month-by-frederick-p-brooks-jr">4. The Mythical Man-Month by Frederick P. Brooks Jr</h3> <div class="image-container"> <p><img src="https://rndthts.dev/images/books/mythical_man_month.jpg" alt="The Mythical Man-Month"></p> </div> <p>Here is a goodreads review to explain the book:</p> <blockquote> <p>I want to print many copies of this book.<br> I want to print many copies and roll them up.<br> I want to roll them up and take them to meetings with my clients.<br> I want to take them to meetings and hit them over the head repeatedly while screaming &ldquo;more&hellip; than&hellip; 30&hellip; years&hellip; and you&hellip; still&hellip; don&rsquo;t&hellip; understand&hellip; anything&hellip; stop&hellip; making&hellip; me&hellip; write&hellip; bad&hellip; software&hellip;!&quot;<br> Seriously.</p></blockquote> <h3 id="5-the-phoenix-project-by-gene-kim-kevin-behr-and-george-spafford">5. The Phoenix Project by Gene Kim, Kevin Behr, and George Spafford</h3> <div class="image-container"> <p><img src="https://rndthts.dev/images/books/the_ph_project.jpg" alt="The Phoenix Project"></p> </div> This book illustrates DevOps principles through storytelling, highlighting collaboration, efficiency, and continuous improvement. While reading, I found myself mapping the characters to real people. <h3 id="6-the-7-habits-of-highly-effective-people-by-stephen-r-covey">6. The 7 Habits of Highly Effective People by Stephen R. Covey</h3> <div class="image-container"> <p><img src="https://rndthts.dev/images/books/7habits.jpg" alt="The 7 Habits of Highly Effective People"></p> </div> If you’ve ever heard the saying, “Listen to understand, not to reply,” but don’t know where it comes from, read this book. I revisit it every 2–3 years, and each time, I find new insights. <h3 id="7-the-five-dysfunctions-of-a-team-by-patrick-lencioni">7. The Five Dysfunctions of a Team by Patrick Lencioni</h3> <div class="image-container"> <p><img src="https://rndthts.dev/images/books/5dysfunctions.jpeg" alt="The Five Dysfunctions of a Team"></p> </div> Primarily a leadership book, but if you work in a team, I think it's definitely worth reading. <h3 id="8-thinking-fast-and-slow-by-daniel-kahneman">8. Thinking, Fast and Slow by Daniel Kahneman</h3> <div class="image-container"> <p><img src="https://rndthts.dev/images/books/thinking_fast_and_slow.jpeg" alt="Thinking, Fast and Slow"></p> </div> This book explores how we make decisions and the cognitive biases that shape our thinking. <h3 id="9-hooked-how-to-build-habit-forming-products-by-nir-eyal">9. Hooked: How to Build Habit-Forming Products by Nir Eyal</h3> <div class="image-container"> <p><img src="https://rndthts.dev/images/books/hooked.png" alt="Hooked: How to Build Habit-Forming Products"></p> </div> I placed this book after Thinking, Fast and Slow because it builds on many of its ideas, applying them to real-world products. <h3 id="10-animal-farm-by-george-orwell">10. Animal Farm by George Orwell</h3> <div class="image-container"> <p><img src="https://rndthts.dev/images/books/animal_farm.jpg" alt="Animal Farm"></p> </div> <blockquote> <p>All animals are equal, but some animals are more equal than others.</p></blockquote> <p>That’s it for now, until next time, happy reading!!!</p> A Declaration of Intent: Why I'm Writing https://rndthts.dev/posts/declaration_of_intent/ Tue, 18 Feb 2025 11:24:40 +0100 https://rndthts.dev/posts/declaration_of_intent/ <p>I should probably have started with this post before writing anything else, but who cares? Probably no one will ever read this, and that&rsquo;s perfectly fine. I&rsquo;m not writing this for others. This blog is just my personal collection of notes and documentation; something I should have been doing for years but never did.</p> <h2 id="motivation">Motivation</h2> <p>I wrote my first &ldquo;Hello, World!&rdquo; program in 8th grade using QBasic, and I was hooked. After a few small programs, I started experimenting with Visual Basic. When you&rsquo;re new to programming; or anything, really, you want something visual. Visuals sell the product. There&rsquo;s that saying: <strong>Rims sell the car.</strong></p> <p><img src="https://rndthts.dev/images/rims.jpg" alt="Rims"> Photo by <a href="https://unsplash.com/@grebenyev?utm_content=creditCopyText&utm_medium=referral&utm_source=unsplash">Vlad Grebenyev</a> on <a href="https://unsplash.com/photos/close-up-photography-of-car-wheel-7eCBiZgyr4E?utm_content=creditCopyText&utm_medium=referral&utm_source=unsplash">Unsplash</a></p> <p>So, my friend and I created our first GUI program in Visual Basic: a periodic table of elements. Visually, it worked. The code? Absolutely terrible. Imagine spaghetti code, multiply it by 100, then multiply that by a <code>rand(5, 10)</code>. It was that bad. I don’t have the code anymore, and that&rsquo;s one of my motivations for writing this blog. But I remember it vividly: massive if-else chains for every element. Yes, for every single element, in multiple places.</p> <p><img src="https://rndthts.dev/images/spaghetti.jpg" alt="Spaghetti"> Photo by <a href="https://unsplash.com/@neonbites?utm_content=creditCopyText&utm_medium=referral&utm_source=unsplash">Thomas Wavid Johns</a> on <a href="https://unsplash.com/photos/a-pile-of-spaghetti-sitting-on-top-of-a-wooden-table-IReDRPiM-KY?utm_content=creditCopyText&utm_medium=referral&utm_source=unsplash">Unsplash</a></p> <p>Who would have thought that, years later, someone would actually pay me to write code professionally?</p> <p>Fast forward 20 years. I’ve been writing code professionally for 12 or 13 years now. Hundreds of small projects, prototypes, interesting applications of design patterns, and problem-solving insights - <strong>gone</strong>. Never documented. Lost to time.</p> <blockquote> <p>Fun fact: almost all the software I’ve written professionally is terminal-based, often running in the background without user interaction. Turns out, if you go fast enough, no one even notices the rims.</p></blockquote> <h2 id="what-will-be-covered">What Will Be Covered</h2> <p>From now on, I’m going to try to document as much as possible. I&rsquo;ll cover topics I find interesting, reimplement old projects, explore tools, and maybe even suggest potential projects.</p> <p>Here are some of the things I want to write about:</p> <ul> <li><strong>Compilation steps</strong> – understanding what happens when you compile code</li> <li><strong>Dear ImGui</strong></li> <li><strong>Ugly and spaghetti code</strong></li> <li><strong>File formats</strong> – exploring Mach-O and ELF</li> <li><strong>Linkers</strong></li> <li><strong>Debuggers</strong> </li> <li><strong>Books</strong> – reviews, short or long, depending on the book</li> <li><strong>Package managers</strong> – how they work and why they matter</li> <li><strong>Meson build system</strong> – why you should care</li> <li><strong>Projects that are good for beginners</strong></li> <li><strong>Test-Driven Development (TDD)</strong> – is it worth the hype?</li> <li><strong>Production-ready Hello World</strong> – making even the simplest programs production-grade</li> <li><strong>LLVM passes and codegen</strong> – digging into compiler internals</li> <li><strong>Assembly and syscalls</strong> – low-level programming insights</li> <li><strong>OpenCV experiments</strong> – exploring computer vision with POCs </li> <li><strong>OpenGL experiments</strong></li> <li><strong>Exploring C++ projects</strong> – possibly a series, maybe weekly :) </li> <li><strong>Exception handling</strong> – what happens under the hood</li> <li><strong>Random industry thoughts</strong> – because this field is wild</li> <li><strong>Agile, Scrum, and Leadership</strong> – reflections on the way software teams work</li> <li><strong>Different personas in software development and management teams</strong></li> <li><strong>Other rndthts</strong> &hellip;</li> </ul> <p>This list will evolve over time, but the goal remains the same: document things I find useful, interesting, or just worth preserving. Also, the order of topics is completely random, and it&rsquo;s far from complete.</p> <p>If, by any chance, someone else stumbles upon this blog and actually finds it useful, well, that&rsquo;s a happy accident! But really, this is just me making up for years of not writing things down. Let&rsquo;s see where this random ride takes us.</p> Compilation Process - Compilation https://rndthts.dev/posts/c_cpp_compilation_process_compile/ Sun, 09 Feb 2025 10:12:45 +0100 https://rndthts.dev/posts/c_cpp_compilation_process_compile/ <p>In the last blog post, we covered the <a href="https://rndthts.dev/posts/c_cpp_compilation_process/">Preprocessing stage</a>. Now, it&rsquo;s time to dive into the Compilation stage.</p> <p><img src="https://rndthts.dev/images/compilation_steps_compile.png" alt="Compilation"></p> <h2 id="what-is-compilation">What is Compilation?</h2> <p>Compilation is the process of converting preprocessed source code (in our case, C or C++ code) into assembly code. This phase is handled by the compiler, which performs various checks and optimizations before generating low-level code.</p> <p>Unlike the preprocessing phase, which merely modifies the code textually, compilation involves deeper analysis and transformation.</p> <blockquote> <p><strong>Note:</strong> To stop the compilation process after the compilation phase, use the -S flag:</p></blockquote> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>gcc/clang -S main.c -o main.s </span></span></code></pre></div><p>Let&rsquo;s explore this with an example:</p> <blockquote> <p>foo.h</p></blockquote> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">foo</span>(<span style="color:#66d9ef">void</span>); </span></span></code></pre></div><blockquote> <p>main.c</p></blockquote> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#75715e">#include</span> <span style="color:#75715e">&#34;foo.h&#34;</span><span style="color:#75715e"> </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> </span></span><span style="display:flex;"><span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">square</span>(<span style="color:#66d9ef">int</span> i) { <span style="color:#66d9ef">return</span> i <span style="color:#f92672">*</span> i; } </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">main</span>() { </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">int</span> a <span style="color:#f92672">=</span> <span style="color:#ae81ff">5</span>; </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">int</span> f <span style="color:#f92672">=</span> <span style="color:#a6e22e">foo</span>(); </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> f <span style="color:#f92672">+</span> <span style="color:#a6e22e">square</span>(a); </span></span><span style="display:flex;"><span>} </span></span></code></pre></div><h2 id="key-stages-of-compilation">Key Stages of Compilation</h2> <h3 id="1-lexical-analysis-tokenization">1. Lexical Analysis (Tokenization)</h3> <p>The preprocessed code is broken down into tokens. For example, the line:</p> <pre tabindex="0"><code>int a = 5; </code></pre><p>will be tokenized into: <code>int</code>, <code>a</code>, <code>=</code>, <code>5</code> and <code>;</code></p> <p>This stage eliminates whitespace and detects unknown symbols. For instance:</p> <pre tabindex="0"><code>int a = 5 ; </code></pre><p>will still end up with the same tokens <code>int</code>, <code>a</code>, <code>=</code>, <code>5</code> and <code>;</code></p> <p>However, this will cause an error: <code>int a = 5 @ 3;</code></p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span>error: expected <span style="color:#e6db74">&#39;;&#39;</span> at end of declaration </span></span><span style="display:flex;"><span> <span style="color:#ae81ff">6</span> <span style="color:#f92672">|</span> <span style="color:#66d9ef">int</span> a <span style="color:#f92672">=</span> <span style="color:#ae81ff">5</span> <span style="color:#960050;background-color:#1e0010">@</span><span style="color:#ae81ff">3</span>; </span></span><span style="display:flex;"><span> <span style="color:#f92672">|</span> <span style="color:#f92672">^</span> </span></span><span style="display:flex;"><span> <span style="color:#f92672">|</span> </span></span></code></pre></div><h3 id="2-syntax-analysis-parsing">2. Syntax Analysis (Parsing)</h3> <ul> <li> <p>Tokens are grouped based on grammar rules to form an Abstract Syntax Tree (AST).</p> </li> <li> <p>The AST represents the hierarchical syntactic structure of the code, abstracting unnecessary details like semicolons or parentheses.</p> </li> <li> <p>This phase ensures that the code structure follows language syntax. Example: <code> int a = 5 // Missing the ;</code></p> </li> </ul> <p>output:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span>error: expected <span style="color:#e6db74">&#39;;&#39;</span> at end of declaration </span></span><span style="display:flex;"><span> <span style="color:#ae81ff">6</span> <span style="color:#f92672">|</span> <span style="color:#66d9ef">int</span> a <span style="color:#f92672">=</span> <span style="color:#ae81ff">5</span> <span style="color:#75715e">// Missing the ; </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#f92672">|</span> <span style="color:#f92672">^</span> </span></span><span style="display:flex;"><span> <span style="color:#f92672">|</span> </span></span></code></pre></div><h3 id="3-semantic-analysis">3. Semantic Analysis</h3> <p>This phase checks for logical correctness:</p> <ul> <li>Ensures variables are declared before use.</li> </ul> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">main</span>() { </span></span><span style="display:flex;"><span> <span style="color:#75715e">// int a = 5; </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#66d9ef">int</span> f <span style="color:#f92672">=</span> <span style="color:#a6e22e">foo</span>(); </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> f <span style="color:#f92672">+</span> <span style="color:#a6e22e">square</span>(a); </span></span><span style="display:flex;"><span>} </span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span> error: use of undeclared identifier <span style="color:#e6db74">&#39;a&#39;</span> </span></span><span style="display:flex;"><span> <span style="color:#ae81ff">8</span> <span style="color:#f92672">|</span> <span style="color:#66d9ef">return</span> f <span style="color:#f92672">+</span> <span style="color:#a6e22e">square</span>(a); </span></span><span style="display:flex;"><span> <span style="color:#f92672">|</span> <span style="color:#f92672">^</span> </span></span></code></pre></div><ul> <li>Ensures type compatibility (e.g., no assigning a string to an integer).</li> </ul> <pre tabindex="0"><code>int a = &#34;hello&#34;; </code></pre><p>Error:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span>error: incompatible pointer to integer conversion initializing <span style="color:#960050;background-color:#1e0010">&#39;</span><span style="color:#66d9ef">int</span><span style="color:#960050;background-color:#1e0010">&#39;</span> with an expression of type <span style="color:#960050;background-color:#1e0010">&#39;</span><span style="color:#66d9ef">char</span>[<span style="color:#ae81ff">6</span>]<span style="color:#960050;background-color:#1e0010">&#39;</span> [<span style="color:#f92672">-</span>Wint<span style="color:#f92672">-</span>conversion] </span></span><span style="display:flex;"><span> <span style="color:#ae81ff">6</span> <span style="color:#f92672">|</span> <span style="color:#66d9ef">int</span> a <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;hello&#34;</span>; </span></span><span style="display:flex;"><span> <span style="color:#f92672">|</span> <span style="color:#f92672">^</span> <span style="color:#f92672">~~~~~~~</span> </span></span></code></pre></div><h3 id="4-ir---intermediate-representation">4. IR - Intermediate Representation</h3> <ul> <li> <p>The compiler converts the AST into an Intermediate Representation (IR) that is platform-independent.</p> </li> <li> <p>IR serves as a bridge between high-level source code and low-level machine code, enabling optimizations.</p> </li> </ul> <p>In future posts, we&rsquo;ll cover this topic in depth, along with various optimizations. For now, let&rsquo;s see how to instruct the compiler to emit this form.</p> <p>To generate LLVM IR using clang:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>clang main.c -S -emit-llvm -o main.ll<span style="color:#e6db74">`</span> </span></span></code></pre></div><p>Unoptimized Version:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-lua" data-lang="lua"><span style="display:flex;"><span>; ModuleID <span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;main.c&#39;</span> </span></span><span style="display:flex;"><span>source_filename <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;main.c&#34;</span> </span></span><span style="display:flex;"><span>target datalayout <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;e-m:o-i64:64-i128:128-n32:64-S128-Fn32&#34;</span> </span></span><span style="display:flex;"><span>target triple <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;arm64-apple-macosx14.0.0&#34;</span> </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>; Function Attrs: noinline nounwind optnone ssp uwtable(sync) </span></span><span style="display:flex;"><span>define i32 <span style="color:#960050;background-color:#1e0010">@</span>square(i32 noundef <span style="color:#f92672">%</span><span style="color:#ae81ff">0</span>) <span style="color:#f92672">#</span><span style="color:#ae81ff">0</span> { </span></span><span style="display:flex;"><span> <span style="color:#f92672">%</span><span style="color:#ae81ff">2</span> <span style="color:#f92672">=</span> alloca i32, align <span style="color:#ae81ff">4</span> </span></span><span style="display:flex;"><span> store i32 <span style="color:#f92672">%</span><span style="color:#ae81ff">0</span>, ptr <span style="color:#f92672">%</span><span style="color:#ae81ff">2</span>, align <span style="color:#ae81ff">4</span> </span></span><span style="display:flex;"><span> <span style="color:#f92672">%</span><span style="color:#ae81ff">3</span> <span style="color:#f92672">=</span> load i32, ptr <span style="color:#f92672">%</span><span style="color:#ae81ff">2</span>, align <span style="color:#ae81ff">4</span> </span></span><span style="display:flex;"><span> <span style="color:#f92672">%</span><span style="color:#ae81ff">4</span> <span style="color:#f92672">=</span> load i32, ptr <span style="color:#f92672">%</span><span style="color:#ae81ff">2</span>, align <span style="color:#ae81ff">4</span> </span></span><span style="display:flex;"><span> <span style="color:#f92672">%</span><span style="color:#ae81ff">5</span> <span style="color:#f92672">=</span> mul nsw i32 <span style="color:#f92672">%</span><span style="color:#ae81ff">3</span>, <span style="color:#f92672">%</span><span style="color:#ae81ff">4</span> </span></span><span style="display:flex;"><span> ret i32 <span style="color:#f92672">%</span><span style="color:#ae81ff">5</span> </span></span><span style="display:flex;"><span>} </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>; Function Attrs: noinline nounwind optnone ssp uwtable(sync) </span></span><span style="display:flex;"><span>define i32 <span style="color:#960050;background-color:#1e0010">@</span>main() <span style="color:#f92672">#</span><span style="color:#ae81ff">0</span> { </span></span><span style="display:flex;"><span> <span style="color:#f92672">%</span><span style="color:#ae81ff">1</span> <span style="color:#f92672">=</span> alloca i32, align <span style="color:#ae81ff">4</span> </span></span><span style="display:flex;"><span> <span style="color:#f92672">%</span><span style="color:#ae81ff">2</span> <span style="color:#f92672">=</span> alloca i32, align <span style="color:#ae81ff">4</span> </span></span><span style="display:flex;"><span> <span style="color:#f92672">%</span><span style="color:#ae81ff">3</span> <span style="color:#f92672">=</span> alloca i32, align <span style="color:#ae81ff">4</span> </span></span><span style="display:flex;"><span> store i32 <span style="color:#ae81ff">0</span>, ptr <span style="color:#f92672">%</span><span style="color:#ae81ff">1</span>, align <span style="color:#ae81ff">4</span> </span></span><span style="display:flex;"><span> store i32 <span style="color:#ae81ff">5</span>, ptr <span style="color:#f92672">%</span><span style="color:#ae81ff">2</span>, align <span style="color:#ae81ff">4</span> </span></span><span style="display:flex;"><span> <span style="color:#f92672">%</span><span style="color:#ae81ff">4</span> <span style="color:#f92672">=</span> call i32 <span style="color:#960050;background-color:#1e0010">@</span>foo() </span></span><span style="display:flex;"><span> store i32 <span style="color:#f92672">%</span><span style="color:#ae81ff">4</span>, ptr <span style="color:#f92672">%</span><span style="color:#ae81ff">3</span>, align <span style="color:#ae81ff">4</span> </span></span><span style="display:flex;"><span> <span style="color:#f92672">%</span><span style="color:#ae81ff">5</span> <span style="color:#f92672">=</span> load i32, ptr <span style="color:#f92672">%</span><span style="color:#ae81ff">3</span>, align <span style="color:#ae81ff">4</span> </span></span><span style="display:flex;"><span> <span style="color:#f92672">%</span><span style="color:#ae81ff">6</span> <span style="color:#f92672">=</span> load i32, ptr <span style="color:#f92672">%</span><span style="color:#ae81ff">2</span>, align <span style="color:#ae81ff">4</span> </span></span><span style="display:flex;"><span> <span style="color:#f92672">%</span><span style="color:#ae81ff">7</span> <span style="color:#f92672">=</span> call i32 <span style="color:#960050;background-color:#1e0010">@</span>square(i32 noundef <span style="color:#f92672">%</span><span style="color:#ae81ff">6</span>) </span></span><span style="display:flex;"><span> <span style="color:#f92672">%</span><span style="color:#ae81ff">8</span> <span style="color:#f92672">=</span> add nsw i32 <span style="color:#f92672">%</span><span style="color:#ae81ff">5</span>, <span style="color:#f92672">%</span><span style="color:#ae81ff">7</span> </span></span><span style="display:flex;"><span> ret i32 <span style="color:#f92672">%</span><span style="color:#ae81ff">8</span> </span></span><span style="display:flex;"><span>} </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>declare i32 <span style="color:#960050;background-color:#1e0010">@</span>foo() <span style="color:#f92672">#</span><span style="color:#ae81ff">1</span> </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>attributes <span style="color:#f92672">#</span><span style="color:#ae81ff">0</span> <span style="color:#f92672">=</span> {...} </span></span><span style="display:flex;"><span>attributes <span style="color:#f92672">#</span><span style="color:#ae81ff">1</span> <span style="color:#f92672">=</span> {...} </span></span><span style="display:flex;"><span>... </span></span><span style="display:flex;"><span>... </span></span></code></pre></div><h3 id="compiler-optimizations">Compiler Optimizations</h3> <p>The compiler optimizes the IR before producing assembly code. Common optimizations include:</p> <ul> <li>Function Inlining</li> <li>Dead Code Elimination</li> <li>Loop Unrolling</li> <li>Loop Invariant Code Motion</li> <li>Merge Functions</li> <li>etc &hellip;</li> </ul> <p>We&rsquo;ll explore these in future posts.</p> <p>Final result, arm64 assembly</p> <blockquote> <p>linux</p></blockquote> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-asm" data-lang="asm"><span style="display:flex;"><span> <span style="color:#a6e22e">.text</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">.file</span> <span style="color:#e6db74">&#34;main.c&#34;</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">.globl</span> <span style="color:#66d9ef">square</span> <span style="color:#75715e">// -- Begin function square </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">.p2align</span> <span style="color:#ae81ff">2</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">.type</span> <span style="color:#66d9ef">square</span>,<span style="color:#a6e22e">@function</span> </span></span><span style="display:flex;"><span>square: <span style="color:#75715e">// @square </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">.cfi_startproc</span> </span></span><span style="display:flex;"><span><span style="color:#75715e">// %bb.0: </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">sub</span> <span style="color:#66d9ef">sp</span>, <span style="color:#66d9ef">sp</span>, <span style="color:#75715e">#16 </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">.cfi_def_cfa_offset</span> <span style="color:#ae81ff">16</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">str</span> <span style="color:#66d9ef">w0</span>, [<span style="color:#66d9ef">sp</span>, <span style="color:#75715e">#12] </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">ldr</span> <span style="color:#66d9ef">w8</span>, [<span style="color:#66d9ef">sp</span>, <span style="color:#75715e">#12] </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">ldr</span> <span style="color:#66d9ef">w9</span>, [<span style="color:#66d9ef">sp</span>, <span style="color:#75715e">#12] </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">mul</span> <span style="color:#66d9ef">w0</span>, <span style="color:#66d9ef">w8</span>, <span style="color:#66d9ef">w9</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">add</span> <span style="color:#66d9ef">sp</span>, <span style="color:#66d9ef">sp</span>, <span style="color:#75715e">#16 </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">.cfi_def_cfa_offset</span> <span style="color:#ae81ff">0</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">ret</span> </span></span><span style="display:flex;"><span>.Lfunc_end0: </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">.size</span> <span style="color:#66d9ef">square</span>, <span style="color:#66d9ef">.Lfunc_end0-square</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">.cfi_endproc</span> </span></span><span style="display:flex;"><span> <span style="color:#75715e">// -- End function </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">.globl</span> <span style="color:#66d9ef">main</span> <span style="color:#75715e">// -- Begin function main </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">.p2align</span> <span style="color:#ae81ff">2</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">.type</span> <span style="color:#66d9ef">main</span>,<span style="color:#a6e22e">@function</span> </span></span><span style="display:flex;"><span>main: <span style="color:#75715e">// @main </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">.cfi_startproc</span> </span></span><span style="display:flex;"><span><span style="color:#75715e">// %bb.0: </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">sub</span> <span style="color:#66d9ef">sp</span>, <span style="color:#66d9ef">sp</span>, <span style="color:#75715e">#32 </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">.cfi_def_cfa_offset</span> <span style="color:#ae81ff">32</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">stp</span> <span style="color:#66d9ef">x29</span>, <span style="color:#66d9ef">x30</span>, [<span style="color:#66d9ef">sp</span>, <span style="color:#75715e">#16] // 16-byte Folded Spill </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">add</span> <span style="color:#66d9ef">x29</span>, <span style="color:#66d9ef">sp</span>, <span style="color:#75715e">#16 </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">.cfi_def_cfa</span> <span style="color:#66d9ef">w29</span>, <span style="color:#ae81ff">16</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">.cfi_offset</span> <span style="color:#66d9ef">w30</span>, -<span style="color:#ae81ff">8</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">.cfi_offset</span> <span style="color:#66d9ef">w29</span>, -<span style="color:#ae81ff">16</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">stur</span> <span style="color:#66d9ef">wzr</span>, [<span style="color:#66d9ef">x29</span>, <span style="color:#75715e">#-4] </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">mov</span> <span style="color:#66d9ef">w8</span>, <span style="color:#75715e">#5 // =0x5 </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">str</span> <span style="color:#66d9ef">w8</span>, [<span style="color:#66d9ef">sp</span>, <span style="color:#75715e">#8] </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">bl</span> <span style="color:#66d9ef">foo</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">str</span> <span style="color:#66d9ef">w0</span>, [<span style="color:#66d9ef">sp</span>, <span style="color:#75715e">#4] </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">ldr</span> <span style="color:#66d9ef">w8</span>, [<span style="color:#66d9ef">sp</span>, <span style="color:#75715e">#4] </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">str</span> <span style="color:#66d9ef">w8</span>, [<span style="color:#66d9ef">sp</span>] <span style="color:#75715e">// 4-byte Folded Spill </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">ldr</span> <span style="color:#66d9ef">w0</span>, [<span style="color:#66d9ef">sp</span>, <span style="color:#75715e">#8] </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">bl</span> <span style="color:#66d9ef">square</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">ldr</span> <span style="color:#66d9ef">w8</span>, [<span style="color:#66d9ef">sp</span>] <span style="color:#75715e">// 4-byte Folded Reload </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">add</span> <span style="color:#66d9ef">w0</span>, <span style="color:#66d9ef">w8</span>, <span style="color:#66d9ef">w0</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">.cfi_def_cfa</span> <span style="color:#66d9ef">wsp</span>, <span style="color:#ae81ff">32</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">ldp</span> <span style="color:#66d9ef">x29</span>, <span style="color:#66d9ef">x30</span>, [<span style="color:#66d9ef">sp</span>, <span style="color:#75715e">#16] // 16-byte Folded Reload </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">add</span> <span style="color:#66d9ef">sp</span>, <span style="color:#66d9ef">sp</span>, <span style="color:#75715e">#32 </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">.cfi_def_cfa_offset</span> <span style="color:#ae81ff">0</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">.cfi_restore</span> <span style="color:#66d9ef">w30</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">.cfi_restore</span> <span style="color:#66d9ef">w29</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">ret</span> </span></span><span style="display:flex;"><span>.Lfunc_end1: </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">.size</span> <span style="color:#66d9ef">main</span>, <span style="color:#66d9ef">.Lfunc_end1-main</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">.cfi_endproc</span> </span></span><span style="display:flex;"><span> <span style="color:#75715e">// -- End function </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">.ident</span> <span style="color:#e6db74">&#34;Ubuntu clang version 18.1.3 (1ubuntu1)&#34;</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">.section</span> <span style="color:#e6db74">&#34;.note.GNU-stack&#34;</span>,<span style="color:#e6db74">&#34;&#34;</span>,<span style="color:#a6e22e">@progbits</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">.addrsig</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">.addrsig_sym</span> <span style="color:#66d9ef">square</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">.addrsig_sym</span> <span style="color:#66d9ef">foo</span> </span></span></code></pre></div><blockquote> <p>macos:</p></blockquote> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-asm" data-lang="asm"><span style="display:flex;"><span> <span style="color:#a6e22e">.section</span> <span style="color:#66d9ef">__TEXT</span>,<span style="color:#66d9ef">__text</span>,<span style="color:#66d9ef">regular</span>,<span style="color:#66d9ef">pure_instructions</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">.build_version</span> <span style="color:#66d9ef">macos</span>, <span style="color:#ae81ff">14</span>, <span style="color:#ae81ff">0</span> <span style="color:#66d9ef">sdk_version</span> <span style="color:#ae81ff">14</span>, <span style="color:#ae81ff">4</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">.globl</span> <span style="color:#66d9ef">_square</span> <span style="color:#75715e">; -- Begin function square </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">.p2align</span> <span style="color:#ae81ff">2</span> </span></span><span style="display:flex;"><span>_square: <span style="color:#75715e">; @square </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">.cfi_startproc</span> </span></span><span style="display:flex;"><span><span style="color:#75715e">; %bb.0: </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">sub</span> <span style="color:#66d9ef">sp</span>, <span style="color:#66d9ef">sp</span>, <span style="color:#75715e">#16 </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">.cfi_def_cfa_offset</span> <span style="color:#ae81ff">16</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">str</span> <span style="color:#66d9ef">w0</span>, [<span style="color:#66d9ef">sp</span>, <span style="color:#75715e">#12] </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">ldr</span> <span style="color:#66d9ef">w8</span>, [<span style="color:#66d9ef">sp</span>, <span style="color:#75715e">#12] </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">ldr</span> <span style="color:#66d9ef">w9</span>, [<span style="color:#66d9ef">sp</span>, <span style="color:#75715e">#12] </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">mul</span> <span style="color:#66d9ef">w0</span>, <span style="color:#66d9ef">w8</span>, <span style="color:#66d9ef">w9</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">add</span> <span style="color:#66d9ef">sp</span>, <span style="color:#66d9ef">sp</span>, <span style="color:#75715e">#16 </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">ret</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">.cfi_endproc</span> </span></span><span style="display:flex;"><span> <span style="color:#75715e">; -- End function </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">.globl</span> <span style="color:#66d9ef">_main</span> <span style="color:#75715e">; -- Begin function main </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">.p2align</span> <span style="color:#ae81ff">2</span> </span></span><span style="display:flex;"><span>_main: <span style="color:#75715e">; @main </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">.cfi_startproc</span> </span></span><span style="display:flex;"><span><span style="color:#75715e">; %bb.0: </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">sub</span> <span style="color:#66d9ef">sp</span>, <span style="color:#66d9ef">sp</span>, <span style="color:#75715e">#32 </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">stp</span> <span style="color:#66d9ef">x29</span>, <span style="color:#66d9ef">x30</span>, [<span style="color:#66d9ef">sp</span>, <span style="color:#75715e">#16] ; 16-byte Folded Spill </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">add</span> <span style="color:#66d9ef">x29</span>, <span style="color:#66d9ef">sp</span>, <span style="color:#75715e">#16 </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">.cfi_def_cfa</span> <span style="color:#66d9ef">w29</span>, <span style="color:#ae81ff">16</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">.cfi_offset</span> <span style="color:#66d9ef">w30</span>, -<span style="color:#ae81ff">8</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">.cfi_offset</span> <span style="color:#66d9ef">w29</span>, -<span style="color:#ae81ff">16</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">stur</span> <span style="color:#66d9ef">wzr</span>, [<span style="color:#66d9ef">x29</span>, <span style="color:#75715e">#-4] </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">mov</span> <span style="color:#66d9ef">w8</span>, <span style="color:#75715e">#5 ; =0x5 </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">str</span> <span style="color:#66d9ef">w8</span>, [<span style="color:#66d9ef">sp</span>, <span style="color:#75715e">#8] </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">bl</span> <span style="color:#66d9ef">_foo</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">str</span> <span style="color:#66d9ef">w0</span>, [<span style="color:#66d9ef">sp</span>, <span style="color:#75715e">#4] </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">ldr</span> <span style="color:#66d9ef">w8</span>, [<span style="color:#66d9ef">sp</span>, <span style="color:#75715e">#4] </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">str</span> <span style="color:#66d9ef">w8</span>, [<span style="color:#66d9ef">sp</span>] <span style="color:#75715e">; 4-byte Folded Spill </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">ldr</span> <span style="color:#66d9ef">w0</span>, [<span style="color:#66d9ef">sp</span>, <span style="color:#75715e">#8] </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">bl</span> <span style="color:#66d9ef">_square</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">ldr</span> <span style="color:#66d9ef">w8</span>, [<span style="color:#66d9ef">sp</span>] <span style="color:#75715e">; 4-byte Folded Reload </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">add</span> <span style="color:#66d9ef">w0</span>, <span style="color:#66d9ef">w8</span>, <span style="color:#66d9ef">w0</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">ldp</span> <span style="color:#66d9ef">x29</span>, <span style="color:#66d9ef">x30</span>, [<span style="color:#66d9ef">sp</span>, <span style="color:#75715e">#16] ; 16-byte Folded Reload </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">add</span> <span style="color:#66d9ef">sp</span>, <span style="color:#66d9ef">sp</span>, <span style="color:#75715e">#32 </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">ret</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">.cfi_endproc</span> </span></span><span style="display:flex;"><span> <span style="color:#75715e">; -- End function </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#a6e22e">.subsections_via_symbols</span> </span></span></code></pre></div><p>That&rsquo;s it for this post! In the next one, we&rsquo;ll cover the <strong>Assembler</strong> phase.</p> Compilation Process - Preprocessing https://rndthts.dev/posts/c_cpp_compilation_process/ Wed, 05 Feb 2025 00:52:25 +0100 https://rndthts.dev/posts/c_cpp_compilation_process/ <p>The compilation process consists of four key steps, as shown in the image below. In this series of blog posts, we’ll explore each of those steps, highlighting the most important aspects and sharing interesting insights along the way. 😊</p> <p><img src="https://rndthts.dev/images/compilation_steps.png" alt="Compilation Steps"></p> <h2 id="preprocessing-ccpp---i">Preprocessing (c/cpp -&gt; .i)</h2> <p>The first phase is preprocessing. The input is a .c or .cpp file, and the output is a .i file. Let’s dive into what happens during this stage. To illustrate, we’ll use the following example:</p> <h3 id="example-1">Example 1</h3> <blockquote> <p>foo.h</p></blockquote> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#75715e">// This is a comment in header file </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">foo</span>(<span style="color:#66d9ef">void</span>); </span></span></code></pre></div><blockquote> <p>main.c</p></blockquote> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#75715e">#include</span> <span style="color:#75715e">&#34;foo.h&#34;</span><span style="color:#75715e"> </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> </span></span><span style="display:flex;"><span><span style="color:#75715e">// We have a macro </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#75715e">#define SQUARE(x) (x * x) </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> </span></span><span style="display:flex;"><span><span style="color:#75715e">#define PI 3.14 </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> </span></span><span style="display:flex;"><span><span style="color:#75715e">/* Our main function </span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * with multi-line comment </span></span></span><span style="display:flex;"><span><span style="color:#75715e"> */</span> </span></span><span style="display:flex;"><span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">main</span>() { </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">int</span> result <span style="color:#f92672">=</span> <span style="color:#a6e22e">foo</span>() <span style="color:#f92672">+</span> <span style="color:#a6e22e">SQUARE</span>(<span style="color:#ae81ff">3</span>); </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">float</span> area <span style="color:#f92672">=</span> PI <span style="color:#f92672">*</span> <span style="color:#ae81ff">5</span> <span style="color:#f92672">*</span> <span style="color:#ae81ff">5</span>; </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> result <span style="color:#f92672">+</span> area; </span></span><span style="display:flex;"><span>} </span></span></code></pre></div><blockquote> <p><strong>Note</strong>: The compilation process can be stopped at any step. In this case, we want to stop it after preprocessing, and to do that, we use the <code>-E</code> flag.</p></blockquote> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>gcc -E main.c -o main.i </span></span></code></pre></div><p>The result:</p> <blockquote> <p>main.i</p></blockquote> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#75715e"># 1 &#34;main.c&#34; </span></span></span><span style="display:flex;"><span><span style="color:#75715e"># 1 &#34;&lt;built-in&gt;&#34; 1 </span></span></span><span style="display:flex;"><span><span style="color:#75715e"># 1 &#34;&lt;built-in&gt;&#34; 3 </span></span></span><span style="display:flex;"><span><span style="color:#75715e"># 418 &#34;&lt;built-in&gt;&#34; 3 </span></span></span><span style="display:flex;"><span><span style="color:#75715e"># 1 &#34;&lt;command line&gt;&#34; 1 </span></span></span><span style="display:flex;"><span><span style="color:#75715e"># 1 &#34;&lt;built-in&gt;&#34; 2 </span></span></span><span style="display:flex;"><span><span style="color:#75715e"># 1 &#34;main.c&#34; 2 </span></span></span><span style="display:flex;"><span><span style="color:#75715e"># 1 &#34;./foo.h&#34; 1 </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">foo</span>(<span style="color:#66d9ef">void</span>); </span></span><span style="display:flex;"><span><span style="color:#75715e"># 2 &#34;main.c&#34; 2 </span></span></span><span style="display:flex;"><span><span style="color:#75715e"># 11 &#34;main.c&#34; </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">main</span>() { </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">int</span> result <span style="color:#f92672">=</span> <span style="color:#a6e22e">foo</span>() <span style="color:#f92672">+</span> (<span style="color:#ae81ff">3</span> <span style="color:#f92672">*</span> <span style="color:#ae81ff">3</span>); </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">float</span> area <span style="color:#f92672">=</span> <span style="color:#ae81ff">3.14</span> <span style="color:#f92672">*</span> <span style="color:#ae81ff">5</span> <span style="color:#f92672">*</span> <span style="color:#ae81ff">5</span>; </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> result <span style="color:#f92672">+</span> area; </span></span><span style="display:flex;"><span>} </span></span></code></pre></div><p>Let&rsquo;s observe the result:</p> <ol> <li>Header File Inclusion - The preprocessor replaces #include directives with the actual contents of the specified header files.</li> <li>Line Control Statements (# Directives)</li> <li>Comments are remove ( single and multi line)</li> <li>Macro Expansion (#define) - The preprocessor replaces macros with their defined values.</li> </ol> <ul> <li><code>int result = foo() + SQUARE(3);</code> -&gt; <code>int result = foo() + (3 * 3);</code></li> <li><code>float area = PI * 5 * 5;</code> -&gt; <code>float area = 3.14 * 5 * 5;</code></li> </ul> <h3 id="example-2">Example 2</h3> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#75715e">#ifdef DEBUG </span></span></span><span style="display:flex;"><span><span style="color:#75715e">#include</span> <span style="color:#75715e">&lt;stdio.h&gt;</span><span style="color:#75715e"> </span></span></span><span style="display:flex;"><span><span style="color:#75715e">#endif </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> </span></span><span style="display:flex;"><span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">main</span>() { </span></span><span style="display:flex;"><span> <span style="color:#75715e">#ifdef DEBUG </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">printf</span>(<span style="color:#e6db74">&#34;Debug mode is enabled.</span><span style="color:#ae81ff">\n</span><span style="color:#e6db74">&#34;</span>); </span></span><span style="display:flex;"><span> <span style="color:#75715e">#endif </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#66d9ef">return</span> <span style="color:#ae81ff">0</span>; </span></span><span style="display:flex;"><span>} </span></span></code></pre></div><ol start="5"> <li>Conditional Compilation (#ifdef, #ifndef, #endif) Since <code>DEBUG</code> was not defined, the output after preprocessing looks like this:</li> </ol> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span>... </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">main</span>() { </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> <span style="color:#ae81ff">0</span>; </span></span><span style="display:flex;"><span>} </span></span></code></pre></div><p>A well-known application of conditional compilation is <strong>include guards</strong>. Consider this simplified example:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#75715e">#include</span> <span style="color:#75715e">&#34;foo.h&#34;</span><span style="color:#75715e"> </span></span></span><span style="display:flex;"><span><span style="color:#75715e">#include</span> <span style="color:#75715e">&#34;foo.h&#34;</span><span style="color:#75715e"> </span></span></span><span style="display:flex;"><span><span style="color:#75715e">#include</span> <span style="color:#75715e">&#34;foo.h&#34;</span><span style="color:#75715e"> </span></span></span><span style="display:flex;"><span><span style="color:#75715e">#include</span> <span style="color:#75715e">&#34;foo.h&#34;</span><span style="color:#75715e"> </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> </span></span><span style="display:flex;"><span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">main</span>() { </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> <span style="color:#ae81ff">0</span>; </span></span><span style="display:flex;"><span>} </span></span></code></pre></div><p>Without include guards, the output after preprocessing might look something like this:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span>... </span></span><span style="display:flex;"><span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">foo</span>(<span style="color:#66d9ef">void</span>); </span></span><span style="display:flex;"><span><span style="color:#75715e"># 2 &#34;main_multi.c&#34; 2 </span></span></span><span style="display:flex;"><span><span style="color:#75715e"># 1 &#34;./foo.h&#34; 1 </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">foo</span>(<span style="color:#66d9ef">void</span>); </span></span><span style="display:flex;"><span><span style="color:#75715e"># 3 &#34;main_multi.c&#34; 2 </span></span></span><span style="display:flex;"><span><span style="color:#75715e"># 1 &#34;./foo.h&#34; 1 </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">foo</span>(<span style="color:#66d9ef">void</span>); </span></span><span style="display:flex;"><span><span style="color:#75715e"># 4 &#34;main_multi.c&#34; 2 </span></span></span><span style="display:flex;"><span><span style="color:#75715e"># 1 &#34;./foo.h&#34; 1 </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">foo</span>(<span style="color:#66d9ef">void</span>); </span></span><span style="display:flex;"><span><span style="color:#75715e"># 5 &#34;main_multi.c&#34; 2 </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> </span></span><span style="display:flex;"><span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">main</span>() { </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> <span style="color:#ae81ff">0</span>; </span></span><span style="display:flex;"><span>} </span></span></code></pre></div><p>Of course, this is a silly example, but in larger projects, this issue can happen unintentionally. For example:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#75715e">#include</span> <span style="color:#75715e">&#34;foo.h&#34;</span><span style="color:#75715e"> </span></span></span><span style="display:flex;"><span><span style="color:#75715e">#include</span> <span style="color:#75715e">&#34;bar.h&#34;</span><span style="color:#75715e"> </span></span></span><span style="display:flex;"><span><span style="color:#75715e">#include</span> <span style="color:#75715e">&#34;tar.h&#34;</span><span style="color:#75715e"> </span></span></span></code></pre></div><p>If both <code>bar.h</code> and <code>tar.h</code> also include <code>foo.h</code>, the compiler processes <code>foo.h</code> multiple times, which can lead to redefinition errors.</p> <p>To prevent multiple inclusions, we use <strong>include guards</strong> like this:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#75715e">#ifndef FOO_H </span></span></span><span style="display:flex;"><span><span style="color:#75715e">#define FOO_H </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> </span></span><span style="display:flex;"><span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">foo</span>(<span style="color:#66d9ef">void</span>); </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#75715e">#endif </span><span style="color:#75715e">// FOO_H </span></span></span></code></pre></div><h3 id="example-3">Example 3</h3> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#75715e">#include</span> <span style="color:#75715e">&lt;stdio.h&gt;</span><span style="color:#75715e"> </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> </span></span><span style="display:flex;"><span><span style="color:#75715e">#define CONCAT(a, b) a##b </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> </span></span><span style="display:flex;"><span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">main</span>() { </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">int</span> <span style="color:#a6e22e">CONCAT</span>(my, Var) <span style="color:#f92672">=</span> <span style="color:#ae81ff">10</span>; <span style="color:#75715e">// Expands to int myVar = 10; </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">printf</span>(<span style="color:#e6db74">&#34;File: %s, Line: %d</span><span style="color:#ae81ff">\n</span><span style="color:#e6db74">&#34;</span>, __FILE__, __LINE__); </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> <span style="color:#ae81ff">0</span>; </span></span><span style="display:flex;"><span>} </span></span></code></pre></div><p>The result:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#75715e">// Ignored the stdio.h </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> </span></span><span style="display:flex;"><span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">main</span>() { </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">int</span> myVar <span style="color:#f92672">=</span> <span style="color:#ae81ff">10</span>; </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">printf</span>(<span style="color:#e6db74">&#34;File: %s, Line: %d</span><span style="color:#ae81ff">\n</span><span style="color:#e6db74">&#34;</span>, <span style="color:#e6db74">&#34;main.c&#34;</span>, <span style="color:#ae81ff">7</span>); </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> <span style="color:#ae81ff">0</span>; </span></span><span style="display:flex;"><span>} </span></span></code></pre></div><ol start="6"> <li>Token Pasting (##) and Stringizing (#)</li> <li>Including Built-in Macros in our example <code>__FILE__</code> and <code>__LINE__</code></li> </ol> <p>The next step in the process is compilation. Stay tuned for the next post!</p> Writing your first pass with LLVM https://rndthts.dev/posts/llvm-first-pass/ Fri, 04 Aug 2023 23:59:01 +0200 https://rndthts.dev/posts/llvm-first-pass/ <p><strong>What is a pass?</strong> Simply put, it is a thing that analyzes or transforms LLVM IR inputs.</p> <p><strong>What are we going to use?</strong> We will use <code>opt</code>. What is <code>opt</code>?</p> <blockquote> <p>The opt command is the modular LLVM optimizer and analyzer. It takes LLVM source files as input, runs the specified optimizations or analyses on it, and then outputs the optimized file.</p></blockquote> <p><img src="https://rndthts.dev/images/opt.png" alt="opt"></p> <p>This is so-called <code>middle end</code>. The input to the opt is <code>LLVM IR</code> and the output is also<code>LLVM IR</code></p> <p>Before we start writing our first pass, we need llvm. We can install it or build it ourselves. I used LLVM 16.</p> <p>We can install llvm using: <code>brew install llvm</code> on MacOS or <code>apt install llvm</code> on Ubuntu. If you decide to build llvm, you can follow the official instructions here: <a href="https://llvm.org/docs/GettingStarted.html#getting-the-source-code-and-building-llvm">https://llvm.org/docs/GettingStarted.html#getting-the-source-code-and-building-llvm</a></p> <p>From this point I will refere to llvm installation directory as <code>LLVM_PATH</code>. To easier follow the rest of the stuff, you can just export <code>LLVM_PATH</code> In my case it was <code>export LLVM_PATH=/opt/homebrew/opt/llvm@16/</code> To test this, we can invoke: <code>$LLVM_PATH/bin/opt --version</code> and this should return something similar to this:</p> <pre tabindex="0"><code>Homebrew LLVM version 16.0.6 Optimized build. Default target: arm64-apple-darwin22.5.0 Host CPU: apple-m1 </code></pre><p>Let&rsquo;s start from the point of how are we going to invoke <code>opt</code></p> <pre tabindex="0"><code>$LLVM_PATH/bin/opt -load-pass-plugin hello.dylib -passes=first -disable-output path/to/input.ll </code></pre><p>We will have to provide our plugin, where our pass (or multiple passes) is defined, and a list of the passes. The plugin is a shared library. <code>opt</code> will load our plugin using <code>dlopen</code> and it will try to find a predefined function name in that plugin to set up the plugin. In this case, it will look for <code>llvmGetPassPluginInfo</code> function to initialize the plugin.</p> <p>From the official documentation</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span><span style="color:#75715e">/// The public entry point for a pass plugin. </span></span></span><span style="display:flex;"><span><span style="color:#75715e">/// </span></span></span><span style="display:flex;"><span><span style="color:#75715e">/// When a plugin is loaded by the driver, it will call this entry point to </span></span></span><span style="display:flex;"><span><span style="color:#75715e">/// obtain information about this plugin and about how to register its passes. </span></span></span><span style="display:flex;"><span><span style="color:#75715e">/// This function needs to be implemented by the plugin, see the example below: </span></span></span><span style="display:flex;"><span><span style="color:#75715e">/// </span></span></span><span style="display:flex;"><span><span style="color:#75715e">/// ``` </span></span></span><span style="display:flex;"><span><span style="color:#75715e">/// extern &#34;C&#34; ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK </span></span></span><span style="display:flex;"><span><span style="color:#75715e">/// llvmGetPassPluginInfo() { </span></span></span><span style="display:flex;"><span><span style="color:#75715e">/// return { </span></span></span><span style="display:flex;"><span><span style="color:#75715e">/// LLVM_PLUGIN_API_VERSION, &#34;MyPlugin&#34;, &#34;v0.1&#34;, [](PassBuilder &amp;PB) { ... } </span></span></span><span style="display:flex;"><span><span style="color:#75715e">/// }; </span></span></span><span style="display:flex;"><span><span style="color:#75715e">/// } </span></span></span><span style="display:flex;"><span><span style="color:#75715e">/// ``` </span></span></span></code></pre></div><p>This means that our plugin should implement this function. Let&rsquo;s quickly check the return type:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span><span style="color:#66d9ef">struct</span> <span style="color:#a6e22e">PassPluginLibraryInfo</span> { </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">uint32_t</span> APIVersion; </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">const</span> <span style="color:#66d9ef">char</span> <span style="color:#f92672">*</span>PluginName; </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">const</span> <span style="color:#66d9ef">char</span> <span style="color:#f92672">*</span>PluginVersion; </span></span><span style="display:flex;"><span> <span style="color:#75715e">/// The callback for registering plugin passes with a \c PassBuilder </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#75715e">/// instance </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#66d9ef">void</span> (<span style="color:#f92672">*</span>RegisterPassBuilderCallbacks)(PassBuilder <span style="color:#f92672">&amp;</span>); </span></span><span style="display:flex;"><span>}; </span></span></code></pre></div><p>So, the minimal version of our plugin looks like this: first.cpp:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span><span style="color:#75715e">#include</span> <span style="color:#75715e">&#34;llvm/Passes/PassBuilder.h&#34;</span><span style="color:#75715e"> </span></span></span><span style="display:flex;"><span><span style="color:#75715e">#include</span> <span style="color:#75715e">&#34;llvm/Passes/PassPlugin.h&#34;</span><span style="color:#75715e"> </span></span></span><span style="display:flex;"><span><span style="color:#75715e">#include</span> <span style="color:#75715e">&#34;llvm/Support/raw_ostream.h&#34;</span><span style="color:#75715e"> </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> </span></span><span style="display:flex;"><span><span style="color:#66d9ef">extern</span> <span style="color:#e6db74">&#34;C&#34;</span> LLVM_ATTRIBUTE_WEAK <span style="color:#f92672">::</span>llvm<span style="color:#f92672">::</span>PassPluginLibraryInfo </span></span><span style="display:flex;"><span>llvmGetPassPluginInfo() { </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> {LLVM_PLUGIN_API_VERSION, <span style="color:#e6db74">&#34;First&#34;</span>, <span style="color:#e6db74">&#34;0.1&#34;</span>, [](llvm<span style="color:#f92672">::</span>PassBuilder <span style="color:#f92672">&amp;</span>PB) { </span></span><span style="display:flex;"><span> llvm<span style="color:#f92672">::</span>errs() <span style="color:#f92672">&lt;&lt;</span> <span style="color:#e6db74">&#34;Register pass builder callback :)</span><span style="color:#ae81ff">\n</span><span style="color:#e6db74">&#34;</span>; </span></span><span style="display:flex;"><span> }}; </span></span><span style="display:flex;"><span>} </span></span></code></pre></div><p>We can build it from command line using:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$LLVM_PATH/bin/clang++ -std<span style="color:#f92672">=</span>c++17 first.cpp -shared -fno-rtti -fno-exceptions <span style="color:#e6db74">`</span>$LLVM_PATH/bin/llvm-config --cppflags --ldflags --system-libs --libs core<span style="color:#e6db74">`</span> -o first </span></span></code></pre></div><p>Before invoking <code>opt</code>, we need the input <code>LLVM IR</code> file. In our case, We will create a simple c source file and compile it to <code>LLVM IR</code>. <code>foo.c</code></p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">foo</span>(<span style="color:#66d9ef">int</span> a, <span style="color:#66d9ef">int</span> b) { </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> a <span style="color:#f92672">+</span> b; </span></span><span style="display:flex;"><span>} </span></span></code></pre></div><p>Compile it using:</p> <pre tabindex="0"><code>$LLVM_PATH/bin/clang -c -S -emit-llvm foo.c </code></pre><p>Run opt with this command</p> <pre tabindex="0"><code>$LLVM_PATH/bin/opt -load-pass-plugin first -passes=hello -disable-output foo.ll </code></pre><p>And, we should get something like this:</p> <pre tabindex="0"><code>Register pass builder callback :) /opt/homebrew/opt/llvm@16/bin/opt: unknown pass name &#39;hello&#39; </code></pre><p>Now we can update the implementation of <code>llvmGetPassPluginInfo</code> to register our pass.</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span><span style="color:#66d9ef">extern</span> <span style="color:#e6db74">&#34;C&#34;</span> LLVM_ATTRIBUTE_WEAK <span style="color:#f92672">::</span>llvm<span style="color:#f92672">::</span>PassPluginLibraryInfo </span></span><span style="display:flex;"><span>llvmGetPassPluginInfo() { </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> {LLVM_PLUGIN_API_VERSION, <span style="color:#e6db74">&#34;First&#34;</span>, <span style="color:#e6db74">&#34;0.1&#34;</span>, [](llvm<span style="color:#f92672">::</span>PassBuilder <span style="color:#f92672">&amp;</span>PB) { </span></span><span style="display:flex;"><span> PB.registerPipelineParsingCallback( </span></span><span style="display:flex;"><span> [](llvm<span style="color:#f92672">::</span>StringRef name, llvm<span style="color:#f92672">::</span>FunctionPassManager <span style="color:#f92672">&amp;</span>FPM, </span></span><span style="display:flex;"><span> llvm<span style="color:#f92672">::</span>ArrayRef<span style="color:#f92672">&lt;</span>llvm<span style="color:#f92672">::</span>PassBuilder<span style="color:#f92672">::</span>PipelineElement<span style="color:#f92672">&gt;</span>) <span style="color:#f92672">-&gt;</span> <span style="color:#66d9ef">bool</span> { </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> (name <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;hello&#34;</span>) { </span></span><span style="display:flex;"><span> FPM.addPass(HelloPass{}); </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> true; </span></span><span style="display:flex;"><span> } </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> false; </span></span><span style="display:flex;"><span> }); </span></span><span style="display:flex;"><span> }}; </span></span><span style="display:flex;"><span>} </span></span></code></pre></div><p><code>registerPipelineParsingCallback</code> has several overloads, but for now, we are interested in function pass, as you can see from the signature of provided lambda.</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span>llvm<span style="color:#f92672">::</span>StringRef name, llvm<span style="color:#f92672">::</span>FunctionPassManager <span style="color:#f92672">&amp;</span>FPM, </span></span><span style="display:flex;"><span> llvm<span style="color:#f92672">::</span>ArrayRef<span style="color:#f92672">&lt;</span>llvm<span style="color:#f92672">::</span>PassBuilder<span style="color:#f92672">::</span>PipelineElement<span style="color:#f92672">&gt;</span> </span></span></code></pre></div><p>If the provided pass name is <code>hello</code>, we instantiate <code>HelloPass</code>. So, let&rsquo;s see the definition of the pass.</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span><span style="color:#66d9ef">struct</span> <span style="color:#a6e22e">HelloPass</span> <span style="color:#f92672">:</span> llvm<span style="color:#f92672">::</span>PassInfoMixin<span style="color:#f92672">&lt;</span>HelloPass<span style="color:#f92672">&gt;</span> { </span></span><span style="display:flex;"><span> llvm<span style="color:#f92672">::</span>PreservedAnalyses run(llvm<span style="color:#f92672">::</span>Function <span style="color:#f92672">&amp;</span>F, </span></span><span style="display:flex;"><span> llvm<span style="color:#f92672">::</span>FunctionAnalysisManager <span style="color:#f92672">&amp;</span>) { </span></span><span style="display:flex;"><span> llvm<span style="color:#f92672">::</span>errs() <span style="color:#f92672">&lt;&lt;</span> <span style="color:#e6db74">&#34;Function name: &#34;</span> <span style="color:#f92672">&lt;&lt;</span> F.getName() <span style="color:#f92672">&lt;&lt;</span> <span style="color:#e6db74">&#39;\n&#39;</span>; </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> llvm<span style="color:#f92672">::</span>PreservedAnalyses<span style="color:#f92672">::</span>all(); </span></span><span style="display:flex;"><span> } </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">static</span> <span style="color:#66d9ef">bool</span> <span style="color:#a6e22e">isRequired</span>() { <span style="color:#66d9ef">return</span> true; } </span></span><span style="display:flex;"><span>}; </span></span></code></pre></div><p>This pass is simple, it will run on functions and print function names. We added our pass to the <code>llvm::FunctionPassManager</code> so that the manager will invoke <code>run</code> on our pass, providing us <code>llvm::Function</code> and <code>llvm::FunctionAnalysisManager</code> In our case we do not even use <code>llvm::FunctionAnalysisManager</code></p> <p>We do not change anything when our pass is invoked, so we return <code>llvm::PreservedAnalyses::all()</code></p> <p>If we now compile again our plugin</p> <pre tabindex="0"><code>$LLVM_PATH/bin/clang++ -std=c++17 first.cpp -shared -fno-rtti -fno-exceptions `$LLVM_PATH/bin/llvm-config --cppflags --ldflags --system-libs --libs core` -o first </code></pre><p>run <code>opt</code></p> <pre tabindex="0"><code>$LLVM_PATH/bin/opt -load-pass-plugin first -passes=hello -disable-output foo.ll </code></pre><p>we get:</p> <pre tabindex="0"><code>Function name: foo </code></pre><p>Now let&rsquo;s update our pass to print the number of arguments as well:</p> <pre tabindex="0"><code> llvm::errs() &lt;&lt; &#34;Arg size: &#34; &lt;&lt; F.arg_size() &lt;&lt; &#39;\n&#39;; </code></pre><p>also, let&rsquo;s add more functions to our <code>foo.c</code> file</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">foo</span>(<span style="color:#66d9ef">int</span> a, <span style="color:#66d9ef">int</span> b) { <span style="color:#66d9ef">return</span> a <span style="color:#f92672">+</span> b; } </span></span><span style="display:flex;"><span><span style="color:#66d9ef">double</span> <span style="color:#a6e22e">bar</span>(<span style="color:#66d9ef">int</span> a, <span style="color:#66d9ef">char</span> b, <span style="color:#66d9ef">short</span> c) { <span style="color:#66d9ef">return</span> a <span style="color:#f92672">+</span> b <span style="color:#f92672">+</span> c; } </span></span><span style="display:flex;"><span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">tar</span>() { <span style="color:#66d9ef">return</span> <span style="color:#ae81ff">42</span>; } </span></span></code></pre></div><p>Compile our plugin! Compile <code>foo.c</code> to <code>LLVM IR</code>. Run <code>opt</code>, we will get:</p> <pre tabindex="0"><code>Function name: foo Function Arg size: 2 Function name: bar Function Arg size: 3 Function name: tar Function Arg size: 0 </code></pre> How to inherit from lambdas? https://rndthts.dev/posts/inherit-from-lambdas/ Wed, 13 Oct 2021 14:54:53 +0100 https://rndthts.dev/posts/inherit-from-lambdas/ <p>What happens behind the scene when lambda is created:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span><span style="color:#66d9ef">auto</span> fun <span style="color:#f92672">=</span> [](<span style="color:#66d9ef">int</span> num) { <span style="color:#66d9ef">return</span> num; }; </span></span></code></pre></div><p><a href="https://cppinsights.io">C++ Insights</a> can be used to see what is going on behind the scene:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">__lambda_1_12</span> </span></span><span style="display:flex;"><span>{ </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span><span style="color:#f92672">:</span> </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">inline</span> <span style="color:#75715e">/*constexpr */</span> <span style="color:#66d9ef">int</span> <span style="color:#66d9ef">operator</span>()(<span style="color:#66d9ef">int</span> num) <span style="color:#66d9ef">const</span> </span></span><span style="display:flex;"><span> { </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> num; </span></span><span style="display:flex;"><span> } </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">using</span> retType_1_12 <span style="color:#f92672">=</span> <span style="color:#66d9ef">int</span> (<span style="color:#f92672">*</span>)(<span style="color:#66d9ef">int</span>); </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">inline</span> <span style="color:#75715e">/*constexpr */</span> <span style="color:#66d9ef">operator</span> retType_1_12 () <span style="color:#66d9ef">const</span> <span style="color:#66d9ef">noexcept</span> </span></span><span style="display:flex;"><span> { </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> __invoke; </span></span><span style="display:flex;"><span> }; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">private</span><span style="color:#f92672">:</span> </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">static</span> <span style="color:#66d9ef">inline</span> <span style="color:#66d9ef">int</span> __invoke(<span style="color:#66d9ef">int</span> num) </span></span><span style="display:flex;"><span> { </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> num; </span></span><span style="display:flex;"><span> } </span></span><span style="display:flex;"><span>}; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>__lambda_1_12 fun <span style="color:#f92672">=</span> __lambda_1_12{}; </span></span></code></pre></div><p>This tells us that lambdas are standard types, and that actually we can inherit from them.</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span><span style="color:#66d9ef">template</span> <span style="color:#f92672">&lt;</span><span style="color:#66d9ef">typename</span> L1, <span style="color:#66d9ef">typename</span> L2<span style="color:#f92672">&gt;</span> </span></span><span style="display:flex;"><span><span style="color:#66d9ef">struct</span> <span style="color:#a6e22e">Combo</span> <span style="color:#f92672">:</span> L1, L2 { </span></span><span style="display:flex;"><span> Combo(L1 l1, L2 l2) <span style="color:#f92672">:</span> L1(std<span style="color:#f92672">::</span>move(l1)), L2(std<span style="color:#f92672">::</span>move(l2)) {} </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">using</span> L1<span style="color:#f92672">::</span><span style="color:#66d9ef">operator</span>(); </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">using</span> L2<span style="color:#f92672">::</span><span style="color:#66d9ef">operator</span>(); </span></span><span style="display:flex;"><span>}; </span></span></code></pre></div><p>Let&rsquo;s create two lambdas:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span><span style="color:#66d9ef">auto</span> l1 <span style="color:#f92672">=</span> []{<span style="color:#66d9ef">return</span> <span style="color:#ae81ff">42</span>;}; </span></span><span style="display:flex;"><span><span style="color:#66d9ef">auto</span> l2 <span style="color:#f92672">=</span> [](<span style="color:#66d9ef">const</span> <span style="color:#66d9ef">int</span> n){ <span style="color:#66d9ef">return</span> n<span style="color:#f92672">*</span>n;} </span></span></code></pre></div><p>When instantiating <code>Combo</code> we will take advantage of <a href="https://en.cppreference.com/w/cpp/language/class_template_argument_deduction">Class Template Argument Deduction</a> from <code>C++17</code></p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span>Combo <span style="color:#a6e22e">combo</span>(l1, l2); </span></span><span style="display:flex;"><span>std<span style="color:#f92672">::</span>cout <span style="color:#f92672">&lt;&lt;</span> combo() <span style="color:#f92672">&lt;&lt;</span> std<span style="color:#f92672">::</span>endl; </span></span><span style="display:flex;"><span>std<span style="color:#f92672">::</span>cout <span style="color:#f92672">&lt;&lt;</span> combo(<span style="color:#ae81ff">3</span>) <span style="color:#f92672">&lt;&lt;</span> std<span style="color:#f92672">::</span>endl; </span></span></code></pre></div><p>A more generic version can be created and used as</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span><span style="color:#66d9ef">template</span> <span style="color:#f92672">&lt;</span><span style="color:#66d9ef">typename</span>... Ls<span style="color:#f92672">&gt;</span> </span></span><span style="display:flex;"><span><span style="color:#66d9ef">struct</span> <span style="color:#a6e22e">Combo</span> <span style="color:#f92672">:</span> Ls... { </span></span><span style="display:flex;"><span> Combo(Ls... ls) <span style="color:#f92672">:</span> Ls(std<span style="color:#f92672">::</span>move(ls))... {} </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">using</span> Ls<span style="color:#f92672">::</span><span style="color:#66d9ef">operator</span>()...; </span></span><span style="display:flex;"><span>}; </span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span><span style="color:#66d9ef">auto</span> l1 <span style="color:#f92672">=</span> [] { <span style="color:#66d9ef">return</span> <span style="color:#ae81ff">42</span>; }; </span></span><span style="display:flex;"><span><span style="color:#66d9ef">auto</span> l2 <span style="color:#f92672">=</span> [](<span style="color:#66d9ef">const</span> <span style="color:#66d9ef">int</span> n) { <span style="color:#66d9ef">return</span> n <span style="color:#f92672">*</span> n; }; </span></span><span style="display:flex;"><span><span style="color:#66d9ef">auto</span> l3 <span style="color:#f92672">=</span> [](<span style="color:#66d9ef">const</span> <span style="color:#66d9ef">int</span> n, <span style="color:#66d9ef">int</span> m) { <span style="color:#66d9ef">return</span> n <span style="color:#f92672">*</span> m; }; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>Combo <span style="color:#a6e22e">combo</span>(l1, l2, l3, [](<span style="color:#66d9ef">const</span> std<span style="color:#f92672">::</span>string<span style="color:#f92672">&amp;</span> s){<span style="color:#66d9ef">return</span> s <span style="color:#f92672">+</span> <span style="color:#e6db74">&#34; &#34;</span> <span style="color:#f92672">+</span> s;}); </span></span><span style="display:flex;"><span>std<span style="color:#f92672">::</span>cout <span style="color:#f92672">&lt;&lt;</span> combo() <span style="color:#f92672">&lt;&lt;</span> std<span style="color:#f92672">::</span>endl; </span></span><span style="display:flex;"><span>std<span style="color:#f92672">::</span>cout <span style="color:#f92672">&lt;&lt;</span> combo(<span style="color:#ae81ff">3</span>) <span style="color:#f92672">&lt;&lt;</span> std<span style="color:#f92672">::</span>endl; </span></span><span style="display:flex;"><span>std<span style="color:#f92672">::</span>cout <span style="color:#f92672">&lt;&lt;</span> combo(<span style="color:#ae81ff">3</span>, <span style="color:#ae81ff">43</span>) <span style="color:#f92672">&lt;&lt;</span> std<span style="color:#f92672">::</span>endl; </span></span><span style="display:flex;"><span>std<span style="color:#f92672">::</span>cout <span style="color:#f92672">&lt;&lt;</span> combo(<span style="color:#e6db74">&#34;cpp&#34;</span>) <span style="color:#f92672">&lt;&lt;</span> std<span style="color:#f92672">::</span>endl; </span></span></code></pre></div><p>First version: <a href="https://godbolt.org/z/TWs3e8raY">https://godbolt.org/z/TWs3e8raY</a></p> <p>Second version: <a href="https://godbolt.org/z/7qvchhvzx">https://godbolt.org/z/7qvchhvzx</a></p> Google Test - Missing Feature https://rndthts.dev/posts/google-test-missing-feature/ Sun, 03 Oct 2021 20:37:24 +0200 https://rndthts.dev/posts/google-test-missing-feature/ <p><strong>Test-Driven Development</strong>. <strong>Red-Green-Refactor</strong>. Let&rsquo;s start. You are working on an awesome project in C++ and for TDD you are using the Google testing framework.</p> <p>A typical scenario when using TDD:</p> <ul> <li>The new behavior is introduced and described by a falling test. <strong>We have RED</strong>.</li> <li>Logic is implemented, the test is PASSING. <strong>We have GREEN</strong>.</li> <li>The last step, <strong>REFACTOR</strong> test and implementation if possible.</li> </ul> <p>After that, we run all the tests and we notice that <strong>we have 17 falling tests</strong>.<br> What about re-running only failing tests? <br> What about re-running the first and last failing tests?</p> <p>This is something that kept popping up to me. Google Test does not support anything like this, so I decided to write my solution. <a href="https://github.com/elvisoric/gtester">Github link</a></p> <h2 id="what-is-it">What is it?</h2> <p>Wrapper around Google tests</p> <h2 id="what-it-solves">What it solves?</h2> <p>It allows you to re-run failed tests as well as to filter those failed tests by using numeric tags</p> <h3 id="how-to-use-it">How to use it?</h3> <ul> <li>Set which executable file will be executed:</li> </ul> <pre tabindex="0"><code>./gtester.py --exe exe_name </code></pre><ul> <li>Run all tests:</li> </ul> <pre tabindex="0"><code>./gtester.py </code></pre><ul> <li>Run just failing tests:</li> </ul> <pre tabindex="0"><code>./gtester.py --run_failing </code></pre><ul> <li>Run several failing tests using tags:</li> </ul> <pre tabindex="0"><code>./gtester.py --run_failing 1 3 </code></pre><h2 id="example">Example</h2> <p><img src="https://rndthts.dev/images/gtester_demo.gif" alt="Demo"></p> Hello World https://rndthts.dev/posts/hello-world/ Thu, 01 Jul 2021 23:59:01 +0200 https://rndthts.dev/posts/hello-world/ <h1 id="hello-world">Hello World</h1> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span><span style="color:#75715e">#include</span> <span style="color:#75715e">&lt;iostream&gt;</span><span style="color:#75715e"> </span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> </span></span><span style="display:flex;"><span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">main</span>(){ </span></span><span style="display:flex;"><span> std<span style="color:#f92672">::</span>cout <span style="color:#f92672">&lt;&lt;</span><span style="color:#e6db74">&#34;Hello World!&#34;</span> <span style="color:#f92672">&lt;&lt;</span> std<span style="color:#f92672">::</span>endl; </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> <span style="color:#ae81ff">0</span>; </span></span><span style="display:flex;"><span>} </span></span></code></pre></div> Piggy Bank Matrix Builder Mon, 01 Jan 0001 00:00:00 +0000 <p>Generate weighted number matrices with a target sum and export production-ready files.</p> Terminal Typer Mon, 01 Jan 0001 00:00:00 +0000 <p>Terminal text simulator for demos, videos, and presentations.</p>