<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Unicorn Developer</title>
    <description>The latest articles on Forem by Unicorn Developer (@pvsdev).</description>
    <link>https://forem.com/pvsdev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1110345%2F0615f05a-4746-4c6f-89ff-a4ef95008a77.png</url>
      <title>Forem: Unicorn Developer</title>
      <link>https://forem.com/pvsdev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/pvsdev"/>
    <language>en</language>
    <item>
      <title>C++ digest: News, helpful resources, &amp; your own programming language as bonus</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Tue, 26 May 2026 12:44:29 +0000</pubDate>
      <link>https://forem.com/pvsdev/c-digest-news-helpful-resources-your-own-programming-language-as-bonus-2njk</link>
      <guid>https://forem.com/pvsdev/c-digest-news-helpful-resources-your-own-programming-language-as-bonus-2njk</guid>
      <description>&lt;p&gt;While the industry debates memory safety, the ISO committee and developers continue shaping the future of a much-loved language, we've gathered the most exciting recent events from the C++ world, along with some useful resources.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr8ik7wj2lqxm7ty72g05.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr8ik7wj2lqxm7ty72g05.png" alt="1376_digestcpp/image1.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The road to C++26: contracts and reflection
&lt;/h2&gt;

&lt;p&gt;The ISO Committee has &lt;a href="https://herbsutter.com/2026/03/29/c26-is-done-trip-report-march-2026-iso-c-standards-meeting-london-croydon-uk/" rel="noopener noreferrer"&gt;finished&lt;/a&gt; the technical work on C++26. During a series of meetings, the committee refined the upcoming standard's feature set, exceeding many expectations. Key additions include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;compile-time reflection, which enables a program to describe its own structure and generate code at compile time;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;std::execution&lt;/code&gt;, a universal framework for asynchronous execution, concurrency, and parallelism;&lt;/li&gt;
&lt;li&gt;the &lt;code&gt;pre&lt;/code&gt;, &lt;code&gt;post&lt;/code&gt;, and &lt;code&gt;contract_assert&lt;/code&gt; contracts, which enable developers to define preconditions, postconditions, and assertions directly in function declarations;&lt;/li&gt;
&lt;li&gt;new parallel algorithms, &lt;code&gt;#embed&lt;/code&gt; for binary data, better metaprogramming capabilities, and many other important updates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both GCC and Clang compilers have already &lt;a href="https://en.cppreference.com/cpp/26" rel="noopener noreferrer"&gt;implemented&lt;/a&gt; most C++26 features during the standardization process, and they'll soon appear in other compilers as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security profiles
&lt;/h2&gt;

&lt;p&gt;Efforts to improve security in the upcoming C++29 continue. Bjarne Stroustrup is &lt;a href="https://www.infoworld.com/article/3839386/c-plus-plus-founder-champions-profiles-for-memory-safety.html" rel="noopener noreferrer"&gt;actively promoting&lt;/a&gt; the concept of C++ Profiles. They're sets of additional rules that developers can apply in their code to ensure security.&lt;/p&gt;

&lt;p&gt;Profiles help prevent common issues, such as null pointer dereferences or buffer overflows. They also provide a unified foundation for improving safety without sacrificing the core strengths of C++.&lt;/p&gt;

&lt;h2&gt;
  
  
  The LLVM 22 update
&lt;/h2&gt;

&lt;p&gt;This spring brought a new release of LLVM 22.1. This update brings a wide range of changes: supporting different architectures and adding advanced memory management tools. Key highlights include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;support for new processors (Intel Nova Lake, Wildcat Lake, RISC-V, and other architectures);&lt;/li&gt;
&lt;li&gt;support for new C++26 features;&lt;/li&gt;
&lt;li&gt;advanced memory control tools (special allocation tagging tokens for memory tracking).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can find the full list of updates on the &lt;a href="https://releases.llvm.org/22.1.0/docs/ReleaseNotes.html" rel="noopener noreferrer"&gt;official website&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Articles
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://blog.jetbrains.com/rust/2025/12/16/rust-vs-cpp-comparison-for-2026/" rel="noopener noreferrer"&gt;Rust vs C++: Competition or Evolution in Systems Programming for 2026&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;C and C++ form the foundation of modern software. Operating systems, databases, game engines, and compilers—they all trace their origins back to these languages. Their speed, power, and reliability made them the choice of many. Today, developers have another choice: Rust. This language incorporates the strengths of C++ and addresses some of its issues like memory safety and undefined behavior. So, what's the best option for a developer? The article author explains in detail cases where Rust or C++ has benefits and also describes the pros and cons of these languages.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/cpp/1347/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1376" rel="noopener noreferrer"&gt;How far does lookup see in C++?&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Placing functions near the types they're intended for is a good practice in C++. However, to properly apply this approach , one should understand how the name lookup mechanisms work as well as where to place functions without violating the language rules. The article author covers the concept of name lookup and explores an argument-dependent lookup (&lt;a href="https://en.wikipedia.org/wiki/Argument-dependent_name_lookup" rel="noopener noreferrer"&gt;ADL&lt;/a&gt;) in particular.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/cpp/1339/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1376" rel="noopener noreferrer"&gt;Silent foe or quiet ally: Brief guide to alignment in C++&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Have you ever wondered how data is stored in computer memory? Each variable occupies space in memory as a sequence of bytes at a specific address. However, access to this data is winding: data first gets into the fast cache, which exchanges data blocks with RAM.&lt;/p&gt;

&lt;p&gt;In this series of articles, the author carefully explains the data alignment mechanism. &lt;a href="https://pvs-studio.com/en/blog/posts/cpp/1340/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1376" rel="noopener noreferrer"&gt;The second part is here&lt;/a&gt;. &lt;a href="https://pvs-studio.com/en/blog/posts/cpp/1369/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1376" rel="noopener noreferrer"&gt;And here's the third one&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/cpp/1366/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1376" rel="noopener noreferrer"&gt;Let's check vibe code that acts like optimized C++ one but is actually a mess&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vibe coding is a hot topic these days. In the article, the author uses a small project called Markus as an example to explain why it's important to understand AI-generated code and be able to see what lies beneath a program's elegant syntax. What do you think of vibe coding? Let us know in the comments!&lt;/p&gt;

&lt;p&gt;To stay up to date on the latest C++ news, follow us on &lt;a href="https://x.com/pvs_studio" rel="noopener noreferrer"&gt;X&lt;/a&gt; and &lt;a href="https://linkedin.com/company/pvs-studio" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;. We post articles by our company's experts, video reviews featuring the latest analyzer updates, event announcements, memes, and much more. Most importantly, you're always welcome to leave comments—we'll be happy to respond!&lt;/p&gt;

&lt;h2&gt;
  
  
  Talks
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=U46fJ2bJ-co" rel="noopener noreferrer"&gt;Creator of C++: Bell Labs, Negative Overhead Abstraction, Mistakes | Bjarne Stroustrup — Ryan Peterman&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this talk, Bjarne Stroustrup, creator of C++ and former Bell Labs researcher, reflects on the origins of C++, tracing its evolution from Simula to a system built on C. He discusses the C++ standards committee, memory safety, AI writing code, zero-overhead abstraction, and what he wishes he'd fought harder for from the start.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=FX63YwZ8OIs" rel="noopener noreferrer"&gt;Lightning Talk: Learning C++ Through Writing Coding Questions — CppCon 2025&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CppCon has shared talks from the last event. In this talk, the speaker explains why creating custom exercises for employee training is one of the best ways to master the knowledge of the modern C++ standards. He also discusses how to go from understanding a language feature to explaining it with code example and implementing it in a project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=84qXqMMDS3I" rel="noopener noreferrer"&gt;Lightning Talk: A C++20 Modules Performance Field Report — Tyler Drake — CppCon 2025&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At CppCon 2025, Tyler Drake shared an interesting field report. He wrapped "header-heavy" third-party libraries into custom C++20 modules. The result: full build time on his laptop dropped by 41.5%, and incremental builds were cut in half—down to just 1 second. A compelling argument for anyone still hesitant to adopt modules due to legacy dependencies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Podcasts
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=RHAGn2BOPA4" rel="noopener noreferrer"&gt;GPU Programming and HLSL with Chris Bieneman — CppCast 407 — C++Weekly Ep 533 — C++ Weekly With Jason Turner&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Jason Turner, Mathieu Ropert, and Chris Bieneman talk about the history of GPU shading languages from DirectX assembly in the early 2000s through today, why HLSL is gradually becoming more C++-like (templates, structs, auto), and where it deliberately draws the line. They discuss current industry trends around AI-generated code, and the difficulties of maintaining floating-point consistency across platforms.&lt;/p&gt;

&lt;p&gt;P.S. When choosing content for the digest, we noticed that they also mentioned our article on analyzing vibe-coded projects. Thank you for your kind words about PVS-Studio, it means a lot to us to hear such positive feedback from you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=qXweoDfdUOY" rel="noopener noreferrer"&gt;Sea of Thieves — Keeping Games Up to Standard — Keith Stockdale — CppCast 406 / C++Weekly 529&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's another episode of CppCast with Jason Turner and Mathieu Ropert. Keith Stockdale, senior software engineer at Rare, brings up the topic about challenges of maintaining large, long-term C++ codebases in game dev. The talk covers modern C++ standards, the effect of compiler-specific code on portability, and the practical realities of upgrading systems such as Unreal Engine in professional studio environments.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.twoscomplement.org/#podcast/measure-twice-optimize-once" rel="noopener noreferrer"&gt;Measure Twice, Optimize Once — Two's Complement Podcast&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this podcast episode, Ben Rady and Matt Godbolt talk about performance optimization: benchmarks and microbenchmarks, real performance problems in software systems. They also discuss how to measure performance before optimization and how to understand profiling noise. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://adspthepodcast.com/2026/05/15/Episode-286.html" rel="noopener noreferrer"&gt;Episode 286: GPU Profiling with NVIDIA Nsight Compute (NCU) — ADSP: The Podcast&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The talk focuses on GPU optimization techniques, profiling tools, and high-performance algorithm design. Marco Salgado explains how GPU workloads often become limited by memory throughput. The speakers examine profiling with NVIDIA Nsight Compute, GPU rotate algorithms, and the role of libraries such as NVComp for GPU-based compression. They also discuss how high-level libraries and languages can outperform hand-written low-level implementations by automatically applying optimizations. &lt;/p&gt;

&lt;h2&gt;
  
  
  A series of talks on how to create your own programming language
&lt;/h2&gt;

&lt;p&gt;C++ is constantly evolving and growing: new useful features appear, making it easier to use, but new challenges also arise. If you want to better understand how any language works, it's worth trying to create your own. &lt;/p&gt;

&lt;p&gt;We invite you to watch a series of talks where we create a custom programming language in a live-coding format. Yuri Minaev, experienced C++ developer and architect at PVS-Studio, will guide you through the journey of mastering C++: from implementing a lexer and a recursive descent method to creating your own evaluator. Less boring theory and more actual coding is a great way to boost your programming skills.&lt;/p&gt;

&lt;p&gt;Want to learn how to create your own programming language? &lt;a href="https://pvs-studio.com/en/webinar/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1376" rel="noopener noreferrer"&gt;Follow the link&lt;/a&gt; and join new webinars! &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fohbop0294ifokx96u3dg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fohbop0294ifokx96u3dg.png" alt="1376_digestcpp/image2.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Thank you for reading our digest! Share with us any other fresh news or events you found noteworthy. You can submit them using our &lt;a href="https://pvs-studio.com/en/about-feedback/?is_question_form_open=true" rel="noopener noreferrer"&gt;feedback form&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Don't forget, PVS-Studio stands guard over your codebase. &lt;a href="https://pvs-studio.com/cppdigest" rel="noopener noreferrer"&gt;Get the 30-day trial promo code here&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>c</category>
      <category>news</category>
    </item>
    <item>
      <title>Unity’s AI agent went public: the developers of a static analysis tool on what that means for code quality</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Fri, 22 May 2026 14:21:23 +0000</pubDate>
      <link>https://forem.com/pvsdev/unitys-ai-agent-went-public-the-developers-of-a-static-analysis-tool-on-what-that-means-for-code-5gb6</link>
      <guid>https://forem.com/pvsdev/unitys-ai-agent-went-public-the-developers-of-a-static-analysis-tool-on-what-that-means-for-code-5gb6</guid>
      <description>&lt;p&gt;In early May, Unity opened its built-in Unity Agent to all users.&lt;/p&gt;

&lt;p&gt;It runs in two modes. In chat mode, the AI assistant suggests improvements to game mechanics and helps track down bugs. In agent mode, it works autonomously: analyzing your project, generating and editing code on its own.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://www.youtube.com/watch?v=pHRZm2BwNQc" rel="noopener noreferrer"&gt;official demo&lt;/a&gt; runs through a workflow: a user builds a game arena, generates a car from reference images, turns it into a playable character, and adds a minigun. The entire thing runs on text prompts, so no code is written manually.&lt;/p&gt;

&lt;p&gt;In the &lt;a href="https://discussions.unity.com/t/unity-ai-s-open-beta-now-live-for-unity-6/1718560?utm_campaign=unity-ai-beta&amp;amp;utm_source=press&amp;amp;utm_content=discussions" rel="noopener noreferrer"&gt;post&lt;/a&gt;, Unity described it as AI taking over the tedious parts, while developers stay in charge of creative direction.&lt;/p&gt;

&lt;p&gt;“Our goal with AI is to help you build better games, faster. Unity AI gives you access to our own in-project agentic assistant, which leverages deep context from your projects and is built specifically for Unity workflows”&lt;/p&gt;

&lt;p&gt;The response was split. Some users worry gaming platforms will be flooded with low-effort projects chasing viral trends. But there’s another concern that gets less attention: code quality.&lt;/p&gt;

&lt;p&gt;The PVS-Studio team builds a static analysis tool for code quality, reliability, and security. Here’s their comment on the Unity update:&lt;/p&gt;

&lt;p&gt;Learn about Medium’s values&lt;br&gt;
“Tools like this are a logical step forward, but their limitations matter too. Generative AI genuinely speeds up development, yet it makes mistakes regularly: wrong logic, unsafe patterns, code that runs but isn’t necessarily safe. The root cause is plain: AI generates code based on probabilities, not strict security requirements.&lt;/p&gt;

&lt;p&gt;That’s where static analyzers come in. Not just to catch bugs, but to systematically check for vulnerabilities before anything ships.&lt;/p&gt;

&lt;p&gt;PVS-Studio has been used in game development for years, by studios and engine teams alike. Part of what makes it effective on game code is a combination of deep code analysis and built-in annotations for many Unity and Unreal Engine functions and classes. That extra metadata lets the tool warn developers when an API is being used incorrectly.&lt;/p&gt;

&lt;p&gt;It also covers optimization. Poor performance hurts players just as much as bugs do. Surely, an AI assistant can also suggest optimizations when prompted, and that’s fine for small projects. But at scale, things slip through: suboptimal ordering of math operations across different data structures, unnecessary allocations, repeated calculations that should be cached.&lt;/p&gt;

&lt;p&gt;PVS-Studio currently has 20 Unity-specific diagnostic rules, as well as general diagnostics tuned to account for how Unity scripts actually work.&lt;/p&gt;

&lt;p&gt;The broader point: the more AI-generated code enters a codebase, the more you need tooling that filters it. SAST tools become a necessary filter, not an optional one. AI and static analysis aren’t in competition, they’re increasingly paired by necessity. Skip the verification layer, and quality and security will erode as AI usage grows.”&lt;/p&gt;

&lt;p&gt;PVS-Studio is a static code analyzer for C, C++, C#, and Java — a SAST tool focused on safety and security defects. Since 2008, it has been used by hundreds of companies worldwide. Over 17 years, the team has reviewed more than 500 open-source projects and written about them extensively: ~1,500 articles published on the PVS-Studio blog.&lt;/p&gt;

&lt;p&gt;The analyzer provides more than 1,100 diagnostic rules covering a wide range of error patterns and security defects, and integrates with major IDEs, game engines (Unity, Unreal Engine), build systems, and CI pipelines, including cloud environments. It can operate in air-gapped setups, maps warnings to CWE and SEI CERT, and supports MISRA standards.&lt;/p&gt;

&lt;p&gt;PVS-Studio is used across mechanical engineering, medicine, finance, construction, and game development.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>unity3d</category>
      <category>gamedev</category>
      <category>news</category>
    </item>
    <item>
      <title>Game++. Part 1.2: C++, game engines, and architectures</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Thu, 21 May 2026 13:34:13 +0000</pubDate>
      <link>https://forem.com/pvsdev/game-part-12-c-game-engines-and-architectures-1pj0</link>
      <guid>https://forem.com/pvsdev/game-part-12-c-game-engines-and-architectures-1pj0</guid>
      <description>&lt;p&gt;This book offers insights into C++, including algorithms and practices in game development, explores strengths and weaknesses of the language, its established workflows, and hands-on solutions. C++ continues to dominate the game development industry today thanks to its combination of high performance, flexibility, and extensive low-level control capabilities.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhne64is8e79ky3sq40x3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhne64is8e79ky3sq40x3.png" alt="1375_chapter_1_pt_2/image1.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  AI
&lt;/h2&gt;

&lt;p&gt;Of all the aspects of game development, AI is my favorite topic. Over the past years, I've spent so much time wrestling with mobs that if I had a dollar for every one stuck in a corner, I'd have bought a house by now. First there were lone enemies, then packs of mobs, then coordinated groups sharing behavior trees (BTs).&lt;/p&gt;

&lt;p&gt;Turns out, not every game actually needs "smart" AI. That sounds counterintuitive, but half the time, a couple of simple scripts that have enemies yelping "Ouch!" on a timer and blindly charging into walls are more than enough to satisfy players. AI isn't magic—it's just code. If your engine supports &lt;code&gt;if&lt;/code&gt;, &lt;code&gt;switch&lt;/code&gt;, coroutines, or timers—congrats: you already have AI support. All the "intelligence" is just a bunch of conditions cleverly disguised as brainpower. But when devs want to go "pro", they usually adopt one or more of the approaches below.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;...Behavior Trees (BT)&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Basically, think of it as a simple priority list: if you are hungry, eat; if you see an enemy, attack; if you are badly injured, flee. Behavior trees (BTs) express decisions as a hierarchy of composite and leaf nodes; each node returns one of three statuses: Success, Failure, or Running.&lt;/p&gt;

&lt;p&gt;Composite nodes—Selector, Sequence, and Parallel—control how child nodes run and implement priorities from the top down. A Selector might order branches such as "health below 20% → flee," "enemy in sight → attack," "hunger above 80% → eat," evaluating them in sequence until one succeeds. Leaf nodes (Action, Condition) perform concrete actions or checks. That structure tends to stay readable—the tree mirrors the intended logic— which is why BTs are widely used in games and work well with visual editors and hot reload, letting designers iterate on AI without recompiling. Still, a BT with 500+ nodes can devolve into spaghetti that nobody can follow, not even whoever wrote it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;...GOAP (Goal-Oriented Action Planning)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;GOAP-style AI starts from a question like: "I want to kill the player. What should I do?" It doesn't simply run a fixed script; it assembles a plan from the actions that exist in the world and the current state. Elegant? Yes. But rolling your own planner is no small job. You must handle resources, conflicting effects, action costs, cycles in the search space, and more. GOAP fits heavy, systemic games and is common at large studios, yet it costs serious engineering time and a strong team to implement and debug.&lt;/p&gt;

&lt;p&gt;Unlike rigid behavior trees or finite state machines, GOAP is largely declarative: you specify actions with preconditions and effects, and the planner searches for a sequence that transforms the current world state into one that satisfies the goal. For a goal such as "kill the player," it might produce something like: acquire a weapon → close with the player → attack. The planner can infer that attacking needs a weapon, getting a weapon may require reaching an armory, and movement depends on being able to move. That yields more natural, adaptive behavior: the NPC can respond to a changing world and replan when conditions shift.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;...FSM (Finite State Machine)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the classic setup with states and transitions—idle → walk → attack → flee. A finite state machine (FSM) is a simple formal model: an entity is always in exactly one of a finite number of states, and it moves between them according to rules driven by events or conditions. The pattern maps cleanly to character and enemy behavior. A player might use states such as idle, walk, run, jump, attack, or dead; an AI mob might use patrol, pursue, attack, retreat, or take cover. Each state bundles its own logic: animations, audio, physics tuning, and which actions are allowed. Transitions hinge on explicit triggers: input, collisions, health thresholds, distance to a target, so behavior stays predictable and comparatively easy to debug.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;...Utility AI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Look at NPC with a handful of possible actions, each runnable only when its requirements are satisfied. The system repeatedly scores every eligible action by utility and picks the strongest candidate, which yields smooth blending between behaviors: none of the brittle gatekeeping typical of finite state machines, none of the explicit planning overhead of GOAP. Once you give that NPC more than about ten actions, though, and tie each utility curve to dozens of parameters, forecasting what it will do in a given situation becomes almost impossible.&lt;/p&gt;

&lt;p&gt;Debugging gets ugly fast—"why did it break into a dance instead of attacking?"—because you must chase every utility term and how they combine. Tuning weights per enemy type or scenario also fights the fact that the architecture keeps chasing locally best moves. That is why production setups often pair Utility AI with an FSM for coarse phases, or restrict scoring to explicit contexts so choices stay interpretable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;...exotic ones: HTN, ML, Neural Nets, RL&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;HTN (Hierarchical Task Network) extends the GOAP idea with hierarchical task decomposition: complex goals are broken into subtasks through a system of methods and primitive actions. It produces structured plans and supports long-term strategic planning for NPCs defined in that way.&lt;/p&gt;

&lt;p&gt;Reinforcement learning (RL) and neural networks promise even more dramatic results: agents that learn strong policies through interaction with the environment, adapt to the player's style, and exhibit emergent behavior.&lt;/p&gt;

&lt;p&gt;The results speak for themselves: AlphaStar in StarCraft II, OpenAI Five in Dota 2, agents that outperform humans in complex strategy games.&lt;/p&gt;

&lt;p&gt;Those successes create an illusion that the technology is ready for broad use, yet training an agent for even a relatively simple game can take millions of rollouts—weeks or months of continuous computation on powerful GPU clusters. A single training run can cost hundreds of thousands of dollars. Moreover, any gameplay change or new mechanic often means restarting training from scratch.&lt;/p&gt;

&lt;p&gt;On top of that, trained models can be hard to reason about. Debugging this kind of "black box" is difficult even for the ML engineers who built it. That is why large studios still tend to reserve ML for targeted uses—procedural generation, player analytics, and similar—while relying on classical methods for core gameplay AI, where predictable behavior and controlled costs matter most.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;...pathfinding&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;A*&lt;/code&gt; (A-star) algorithm and its variants are the workhorses of game AI: they search a discrete navigation graph efficiently by combining the cost-so-far from the start with a heuristic estimate of the remaining cost to the goal. Practical tweaks turn that elegant textbook algorithm into something that can absorb hundreds of path requests per frame.&lt;/p&gt;

&lt;p&gt;The harder problems are usually building and updating the graph, and turning graph paths into motion in the real level. &lt;code&gt;A*&lt;/code&gt; outputs a polyline of nodes, but the character still has to move along it with a body, inertia, clearance, and dynamic clutter in mind. Familiar failure modes include corner snagging on coarse geometry, jams in tight choke points, trouble routing around movers (other NPCs, the player, physics props), and fragile vertical routing (ladders, ledges, jumps). Even so, &lt;code&gt;A*&lt;/code&gt; (plus navmesh or grid tooling around it) remains the backbone of most shipped navigation, while every new map still means tuning geometry and chasing edge cases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;... navmesh&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Finally, the bedrock of in-game navigation: a navigation mesh (navmesh) turns messy 3D level geometry into a discrete walkable surface made of polygons and the links between them. Each polygon is (usually) a walkable region; shared edges or portals are where the agent can move from one patch to the next.&lt;/p&gt;

&lt;p&gt;A good navmesh trades fidelity against cost. Too much detail spawns unnecessary complexity and slows search; too little detail skews paths and causes characters to hug corners or snag. Today's pipelines lean on automatic bakes. Recast &amp;amp; Detour—the open-source stack behind many Unity and Unreal workflows—voxelizes or samples the level and outputs a mesh using agent parameters (radius, height, max step, max slope, and so on). Commercial tools and in-house bakes at big studios add more specialized rules and are tuned to specific engines and production needs.&lt;/p&gt;

&lt;p&gt;No generator, however sophisticated, truly understands a level. It does not know a nook is meant for stealth, that a footbridge is scripted to break, or that a ladder needs a bespoke climb. Common bake failures include links through paper-thin walls or open windows, bogus connections between platforms at different heights, doors/elevators/destructibles treated as static, and broken islands in dense spaces.&lt;/p&gt;

&lt;p&gt;So modern workflow is automation plus hand pass: designers place jump links, cover hints, corner fixes, and mark areas with special costs, speed scales, or unit-class rules. Without that manual nav polish, the fanciest decision-making stack is like a wheelbarrow with a wheel missing—it can decide what to do, but it still cannot reliably carry it out in the real geometry.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;...AI isn't about "smart enemies"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Game AI is mostly about selling the illusion of intelligence. Players need reactions, pressure, and the occasional surprise. Behind the curtain it is still if statements, switches, and a pile of navmesh—exactly the kind of machinery they should not have to think about. "Good" AI is not the same as genuinely smart AI: the job is to entertain and stave off boredom, not to pass a Turing test. A slow-witted opponent is fine if it behaves the way the player expects. A predictable opponent is fine, too: readable patterns make mastery feel earned. A hand-authored script is fine if it is reliable, fun to play against, and does not break the world.&lt;/p&gt;

&lt;p&gt;In short, the goal is not to be smart; the goal is to seem smart. If the player believes they are facing something clever, you have done the important part of the work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scripts and configs
&lt;/h2&gt;

&lt;p&gt;Embedded gameplay logic often lives in scripting layers: Lua, Python, JavaScript, AngelScript, and similar, especially when the core engine is built in C++. Those languages tend to fail more gracefully at runtime and can save a lot of iteration time. Even if you are writing an engine from scratch, it pays to plan for scripting early and to keep the host language's strengths and limits in mind: that reduces glue cost and keeps integration straightforward.&lt;/p&gt;

&lt;p&gt;Building an engine still means writing plenty of code; there is no real shortcut. Which language should you pick? Frankly, what you already know well matters more than the label on the tin. A seasoned developer will squeeze much more out of performance-sensitive paths in a familiar language and will sidestep the usual traps more reliably. Low-level options such as C++ give you clear control over resources, but they expect solid architecture judgment and a firm grasp of how systems fail and scale.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;...it's not about performance or FPS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Script layers and data-driven configs exist mainly so designers can iterate quickly and so less engineering-heavy teammates can contribute safely. High-level languages—Lua, Python, a bespoke DSL, or similar—give you a flexible sandbox for gameplay prototyping: tune balance, try new mechanics, and adjust AI behavior without kicking off a full native rebuild or pulling an engineer into every tweak.&lt;/p&gt;

&lt;p&gt;With a low-level-only workflow, even small changes often mean compile, link, and deploy—minutes to hours, depending on the codebase. Interpreted scripts plus JSON/XML-style configuration draw a clean boundary between the stable C++ core and the volatile content layer. You pay a modest runtime tax (parse time, interpretation) but you buy shorter iteration loops, easier A/B experiments, and content patches that do not require shipping new binaries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;...it's about convenience and development speed&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Scripting enables a fundamentally different development rhythm: the write–test–fix loop collapses to seconds because languages are interpreted and many setups support hot reload. You can nudge an enemy's detection logic or aggression tuning and see the outcome immediately in-game. Modern engines add live inspectors, debug consoles, and visual debugging hooks - exactly what you want when design asks for constant pivots. Standing up several AI behavior variants in one evening becomes realistic, so teams can experiment without treating every idea like a production milestone. Compared with the C++ pipeline, where each tweak might cost thirty seconds to minutes of rebuild time, a script-forward workflow is simply easier to stay "in the zone" with.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;...surprisingly, it's also about safety&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sandboxed scripting is mostly about isolation: each script runs inside a controlled environment with a deliberately narrow API. In Lua, for instance, you can spin up separate VMs (&lt;code&gt;lua_State&lt;/code&gt;) with their own global tables and expose only the bindings you intend—blocking raw filesystem access, sockets, process spawning, and similar primitives unless you explicitly whitelist them. Typical gameplay-facing surfaces might look like &lt;code&gt;SpawnActor()&lt;/code&gt;, &lt;code&gt;GetPlayerHealth()&lt;/code&gt;, or &lt;code&gt;PlaySound()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can also cap risk operationally: maximum CPU time per script tick, memory budgets, instruction budgets, call counts, recursion depth (whatever your VM exposes) and hard-stop the script when a limit trips. When script code misbehaves, the interpreter can usually trap the error, log context, and let the native core keep running. Native plugins and dynamically loaded modules are different: they generally execute in-process with the engine, so a stray pointer or buffer overrun can still take the whole process down.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;...it's about overall project reconfigurability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hard-coded literals in C++ become architectural friction: every tweak to an AI tunable forces a full native iteration: preprocess, compile, link, ship bits and before anyone can feel the change in-game. That pain shows up fastest when you are chasing numbers such as damage modifiers, nav penalties, aggression thresholds, or weapon timings. The straightforward fix is to push anything gameplay-facing into external data (JSON/XML/INI), spreadsheets, custom DAG formats, or database rows, so designers can rebalance without touching source. Many engines layer reflection-style property systems on top so values hydrate from disk and can be edited live in inspectors.&lt;/p&gt;

&lt;p&gt;Hot reload for scripts usually boils down to watching files and re-importing modules: the tooling notices that a script changed, reloads that unit inside the running interpreter, and keeps the native host process alive. That workflow matters when you are iterating on AI rules, event handlers, or broader mechanics and want feedback without a reboot cycle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;...it'so a door for the community&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;User-generated content needs a low floor for contributors: easy tooling and modest prerequisites. Shipping a mod-facing C++ surface usually means an SDK with headers, build docs, ABI promises, and matrix-testing across compiler versions and platforms: Visual Studio generations, GCC, Clang, and whatever else your players use. Scripting sidesteps much of that: the interpreter already ships inside the game, so modders mainly need an editor, your dialect docs, and enough syntax to stay out of trouble.&lt;/p&gt;

&lt;p&gt;A modular script API also gives you a narrow contract: gameplay-facing calls stay stable while native internals churn. Native plugins are different—engine upgrades often force rebuilds, toolchain bumps, and subtle breakage even when nothing "meaningful" changed on paper. Script packs tend to keep working across releases as long as the exposed bindings and semantics stay compatible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;...you can't please everyone&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Lua&lt;/strong&gt;&lt;/em&gt; has become the de facto gold standard for embedded gameplay scripting: small runtime, fast enough for tight loops, straightforward C/C++ binding, and oceans of examples and reference material. Most titles drive it from a single gameplay thread; when teams need parallelism, they typically spin up separate Lua states (or isolate work carefully), rather than treating one VM as freely multithreaded.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Python's&lt;/strong&gt;&lt;/em&gt; ecosystem is deep and the syntax is approachable, but shipping it inside an engine is often painful: interpreter startup, packaging, the GIL, and embedding details can consume engineering time you would rather spend on gameplay. That friction pushes many projects toward Lua for in-engine scripting.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;JavaScript&lt;/strong&gt;&lt;/em&gt;, through embeddable engines (V8, QuickJS, etc.), can deliver strong throughput and reasonable memory use—modern JIT/AOT JS stacks are mature, and for some teams they are a credible alternative to the usual Lua route.&lt;/p&gt;

&lt;p&gt;Smaller embeddables—&lt;em&gt;&lt;strong&gt;AngelScript&lt;/strong&gt;&lt;/em&gt;, &lt;em&gt;&lt;strong&gt;Wren&lt;/strong&gt;&lt;/em&gt;, &lt;em&gt;&lt;strong&gt;Squirrel&lt;/strong&gt;&lt;/em&gt;, &lt;em&gt;&lt;strong&gt;ChaiScript&lt;/strong&gt;&lt;/em&gt;, and friends—fill niches. They trade different ergonomics and feature sets, and could have been stronger contenders if Lua had not become the default reference point; today they are usually judged against that baseline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Networking&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It is no secret that everyone dreams about it: persistent worlds, co-op, PvP, MMO-scale ambitions, or even simple player chat. Then you crack open Wireshark and your dreams narrow to one thing—getting any of it to actually run.&lt;/p&gt;

&lt;p&gt;Here is the good news first: your game may not need networking at all. If you are building something offline—a puzzle game, a platformer, or "SimTower but with toads"—you can happily ignore the whole topic. If "multiplayer" suddenly sounds tempting, though, tighten your seatbelt. You are stepping onto a road where everything matters, and there is no universal architecture that fits every title.&lt;/p&gt;

&lt;p&gt;Modern languages such as C#, Rust, or Go ship tolerable ergonomics for sockets—async IO, nice coroutines, that sort of thing. In C++ (you have my sympathies) you will probably reach for a battle-tested third-party stack such as RakNet, ENet, or similar. None of them feel "brand new," but they have shipped in countless titles.&lt;/p&gt;

&lt;p&gt;Sockets are only the handshake at the door. Establishing a connection is roughly one percent of the job; the interesting problems start immediately afterward. What exactly is a "networking engine," anyway? Good question—I asked myself the same thing while hacking together my first co-op prototype. I never got a crisp definition, but I collected a long list of features you suddenly care about, which I will walk through next.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;...state synchronization&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the bedrock of multiplayer, and also one of the hardest parts of network programming. Every participant runs their own local simulation of the world, yet those simulations must stay compatible enough that play feels coherent. Perfect lockstep is not achievable in principle: latency means that by the time news of one player's action reaches everyone else, the situation may already have moved on.&lt;/p&gt;

&lt;p&gt;So, teams pick strategies that match the genre. Turn-based games can pause until acknowledgements arrive. Real-time titles usually trade purity for responsiveness—either constrain pacing to the worst connection, or predict locally and reconcile mistakes afterward. Another common pattern is an authoritative server: simple conceptually, tough on high-latency clients who constantly receive corrections.&lt;/p&gt;

&lt;p&gt;Fast-moving interactions are where it gets ugly—mutual kills, two players grabbing the same pickup, racing inputs on a contested objective. Some arbiter (often time-stamped server adjudication plus latency-aware rewinds) has to decide what "happened first," even though each player experienced different delays. Get that wrong and players see constant rewind-snaps—"rubberbanding"—as the simulation reconciles against what actually occurred.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;...input prediction and rollback netcode&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Rollback netcode keeps fast games playable even when latency is high. The idea is straightforward: do not stall the simulation waiting for remote input—advance locally using predictions. When real inputs finally arrive, compare them with what you assumed; if they disagree, rewind to a saved checkpoint and replay forward with the corrected inputs.&lt;/p&gt;

&lt;p&gt;Shippable rollback stacks almost always need fast snapshotting or equivalent bookkeeping: enough history to restore an earlier timestep and resimulate deterministically. Practically, that means storing periodic world snapshots or compact state deltas—positions, velocities, animation phases, RNG seeds, anything that affects simulation outcomes—plus the input stream needed to replay.&lt;/p&gt;

&lt;p&gt;When a mismatch fires, you load the snapshot at the divergence point and fast-forward to "now," applying the true inputs along the way. Done well, players barely perceive the correction—the game keeps feeling crisp even around 100–150 ms RTT, where naive lockstep feels awful.&lt;/p&gt;

&lt;p&gt;The catch is engineering cost: the gameplay simulation must be deterministic and replay-safe, which often forces broad refactors across gameplay code, physics hooks, and fixed-point or controlled-float policies. Saving "the entire world every frame" is the textbook mental model; production engines usually optimize that snapshot strategy, but the obligation remains the same —you must be able to reconstruct the past quickly enough to hide latency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;...interpolation, extrapolation, smoothing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Networked games constantly deal with messy delivery: packets show up at uneven intervals, drop entirely, or land out of order. If you simply apply each update as it arrives, motion looks choppy and often unplayable. Interpolation smooths that out by blending between known samples, if you know a player was at point A at time T1 and at point B at time T2, you can render a continuous motion between those keys instead of snapping.&lt;/p&gt;

&lt;p&gt;Extrapolation pushes further: you guess where something will be next from its current velocity and heading so you can keep moving it while you wait for fresh data. The trade-off is accuracy— the longer you predict ahead, the more likely the object suddenly stops or turns, and your guess diverges from reality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;...secure communication protocol&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Network protocol security begins with never trusting the wire blindly. Every inbound message should be validated: correct framing, sane ranges, and consistency with what that peer is allowed to do right now. If you apply client-supplied state without checks, you invite classic exploits: arbitrary teleports, inventory stuffing, stat inflation, and worse.&lt;/p&gt;

&lt;p&gt;Authentication and authorization harden the perimeter: only legitimate clients should join a session, and each peer should only act within its role. Sessions normally start with identity proof—tokens, signatures, or platform-issued tickets—and critical operations should re-check permissions and freshness. Rotate credentials on a sensible schedule, enforce validation on high-risk actions, and treat session keys as a second line of defense so a stolen long-lived password does not instantly mean game over.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;...encryption (you don't get paranoid for nothing)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Encryption in games is not paranoia, it is basic hygiene. Even casual titles move data that should stay private: progression, virtual currency, handles tied to accounts. Modern capture tools are so approachable that unencrypted traffic is trivially observable. TLS is the usual baseline for protecting bytes on the wire, but cryptography is not free: handshakes cost round trips, and ciphered payloads add CPU to margins that can sting in latency-sensitive modes where tens of milliseconds matter. That is why many realtime stacks blend approaches, such as lighter session crypto for steady-state updates, selective encryption for the highest-risk fields, or tuned stacks built for games and while still refusing to ship gameplay plaintext that trivially enables spoofing and griefing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;...object replication&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In a multiplayer game, the same logical object often exists in several places at once: on the server, on each client, and sometimes in more than one representation on the same machine (for example, authoritative versus predicted). The server copy typically owns the facts that matter for outcomes (health, transforms, inventory counts), while what you render locally may be interpolated, extrapolated, or rolled back.&lt;/p&gt;

&lt;p&gt;A replication layer must choose what to sync, how often, and to whom. Private facts (full inventory loadouts, quest flags, hidden traps) should narrowcast to the owning player; public signals (rough pose, equipped silhouette, team tint) can broadcast to everyone who needs them for rendering or fairness. Delta compression and other bandwidth tricks shrink payloads, but each trick adds edge cases you must reason through when state diverges.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;...logging and debugging&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Logging in networked games is not merely an ops checkbox. For contentious bugs you often want an audit trail for player inputs, meaningful state transitions, and sometimes even packet-level breadcrumbs when you can afford it.&lt;/p&gt;

&lt;p&gt;The catch is volume: a busy title can spill gigabytes per hour if you log naively. Production setups therefore rate-limit, sample, struct-tag, and compress, and they aggressively drop chattier channels in hot paths.&lt;/p&gt;

&lt;p&gt;Structured logs (timestamps, build ids, match ids, player ids, entity ids) are what let you rebuild a story after the fact. When a report says "my unit turned into a different type," you need a thread you can follow: spawn time, command stream, authority changes, template swaps, replication apply order. Without that kind of chain, the bug becomes guesswork.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;... dealing with cheaters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Fighting cheaters is a slow arms race, and the house does not win every round. Every mitigation invites a countermeasure; every anti-cheat update trains tooling to adapt faster. The structural issue is simple: part of your game executes on hardware the attacker owns. Anything you ship to the client can be inspected, patched, replayed, or spoofed at some level of effort.&lt;/p&gt;

&lt;p&gt;Server authority is still your backbone: validate outcomes and sanity-check inputs so blatant lies die server-side. Pure perfection would mean simulating everything centrally, which quickly collides with responsiveness and cost, so teams settle on layered checks on the moments that matter.&lt;/p&gt;

&lt;p&gt;Client-side anti-cheat scans memory and modules for known signatures and anomalies. It can help, but it walks straight into trust and privacy debates: kernel drivers and elevated monitors feel invasive, players hesitate to install them, and false positives annoy legitimate setups from capture tools to security suites.&lt;/p&gt;

&lt;h2&gt;
  
  
  UI
&lt;/h2&gt;

&lt;p&gt;You can ship a game with no physics, no AI, even no sound. Shipping without UI is almost impossible. These days a completely UI-less title reads as intentional avant-garde indiesperimentation. Besides, you still need somewhere to put New Game and Quit.&lt;/p&gt;

&lt;p&gt;On paper it sounds trivial: draw a few buttons, drop in labels, maybe a slider. Then reality arrives. Interactive widgets accumulate states. A button is not one bitmap; it is idle, hovered, pressed, focused, disabled, and sometimes half a dozen custom variants. Same story for fields, toggles, lists.&lt;/p&gt;

&lt;p&gt;Hierarchy piles on complexity. Modern screens are trees: a button lives inside a row inside a panel inside a sheet that might not exist until a tab opens. Each layer needs layout, clipping, focus routing, and visibility rules that do not fight each other.&lt;/p&gt;

&lt;p&gt;Coordinate spaces make UI math fiddly. Meshes live in one world space; UI fragments flip between pixel screenspace, scaled logical units, and parent-relative boxes. Hit testing, anchoring, DPI scaling, and safe areas all sit on top of that stack.&lt;/p&gt;

&lt;p&gt;Input parity is another whole axis. Desktop expects mouse precision and keyboard traversal; mobile expects fat fingers and gestures; consoles expect focus rings and analog navigation. One layout rarely fits all without deliberate affordances.&lt;/p&gt;

&lt;p&gt;Polish is where hobby UI dies and production UI begins: transitions, micro-motion, feedback on press, disabled styling that still reads clearly. None of that is mere ornament; it is what separates "dead controls" from something that feels alive.&lt;/p&gt;

&lt;p&gt;And then you notice the trap: you set out to ship a game, but you are halfway to authoring a mini framework that may never leave this codebase. Even when you embed a mature stack (Scaleform is better than its reputation, for what it is worth), you still owe integration work: input translation, event bubbling, font atlases, shader passes, batching, localization hooks.&lt;/p&gt;

&lt;p&gt;So yes, UI is structured, layered, platform-sensitive work that teams routinely underestimate. It is still worth doing properly at least once, even in a small scope. Just do not expect weekend one to reproduce Unity UI, Unreal Slate, or the entire HTML ecosystem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tools
&lt;/h2&gt;

&lt;p&gt;Not every engine or game needs a heavyweight toolchain around it, and that should not surprise anyone. Sometimes a handful of Python glue scripts is enough. Many commercial stacks ship editors that feel like an IDE crossed with a DCC app: place entities, tweak materials and shaders, tune physics, scrub animations, poke UI, and scrub changes live.&lt;/p&gt;

&lt;p&gt;Building an editor that polished is almost as expensive as building the runtime itself. For a small custom engine, chasing Unity-parity chrome is usually a bad ROI: months disappear into docking layouts and undo stacks you never needed.&lt;/p&gt;

&lt;p&gt;Still, do not ignore small tools. A few evenings of scripting for bake helpers, batch exporters, or sanity validators routinely buys back weeks of manual slog later.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;...level converters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Custom binary schemas exist because you often want load paths that map cleanly onto engine structs and arrays with minimal translation cost.&lt;/p&gt;

&lt;p&gt;Text interchange formats such as JSON or XML pay for human readability at runtime: lexing, parsing, string-to-number conversion, heap churn. A well-designed packed blob can mmap or fread straight into layouts you already use in simulation, which matters when a level streams thousands of transforms, material handles, and tagging metadata.&lt;/p&gt;

&lt;p&gt;Binary pipelines also give you room for embedded compression, baked LOD chains, precooked nav data, hash tables, whatever preprocessing saves milliseconds on the critical path.&lt;/p&gt;

&lt;p&gt;Conversion tooling ties into normal asset workflows: watch folders, rebuild packs when sources change, split authoring formats from shipping blobs so artists keep familiar exporters while engineers evolve on-disk layouts or platform-specific variants without forcing daily disruption.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;...asset validation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Asset validation is one of the few things that cheaply pays for build integrity: it blocks bad data before it poisons a milestone. Validators walk reference graphs, because every serious asset points at other assets through GUIDs, source paths, or custom handles, and a missing link is a late-night crash you do not want in QA.&lt;/p&gt;

&lt;p&gt;They also enforce content rules: materials must resolve textures, mesh chunks must bind valid skeletons, animation clips must line up with rig definitions, shader permutations must exist for the platforms you actually ship.&lt;/p&gt;

&lt;p&gt;Hook those checks into CI and the content bake so failures surface with filenames, not mystery repros. On big teams, that is how you keep an artist's innocent rename from silently deleting someone else's dependency three departments away.&lt;/p&gt;

&lt;p&gt;Time invested in tooling should pay rent: if a workflow still means hand-editing two hundred lines of JSON, a small exporter or inspector script will usually earn its keep faster than another meeting about process. You still should not build a glittering editor "because engines have editors," but targeted automation is rarely wasted effort.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;

&lt;p&gt;Eventually the parts exist: rendering, audio, data, physics, UI, maybe AI and scripts. The missing question is how you wire it all into something that runs as one product. A few established patterns keep showing up in production codebases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;...no architecture is also architecture&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After fighting overbuilt frameworks, many small teams fall back to a deliberately dumb architecture: a handful of independent libraries, each owning one slice of the problem. You wrap rendering behind a gfx module, audio behind audio, streaming behind assets, polling behind input. Modules stay loosely coupled on purpose; nothing magically knows about anything else unless you wire the calls.&lt;/p&gt;

&lt;p&gt;That was the default posture of late-nineties and early-aughts codebases. It is quick to stand up, easy to reason about in small scopes, and leaves execution order entirely visible.&lt;/p&gt;

&lt;p&gt;Discipline becomes the hidden dependency: without scene graphs or forced pipelines, nothing stops you from forgetting a step.&lt;/p&gt;

&lt;p&gt;Scale hurts first in your head: the call graph sprawls, initialization order turns fragile, and regressions arrive as subtle sequencing bugs. UI stops refreshing after a content reload, music fails to cue on level transition, physics wakes before assets finish streaming. Each fix is manual glue, because the missing piece was never "library quality," it was composition.&lt;/p&gt;

&lt;p&gt;Ironically, the wiring you tried to postpone is the architecture. Evading structure does not delete it; it just relocates the burden into ad hoc calls sprinkled everywhere.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;...godobject is also architecture&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Large game engines like Unity, Unreal, Godot, CryEngine, Dagor, and others often adopt an approach based on a single base class. Typically named &lt;code&gt;Object&lt;/code&gt;, &lt;code&gt;Entity&lt;/code&gt;, &lt;code&gt;GameObject&lt;/code&gt;, &lt;code&gt;Actor&lt;/code&gt;, or similar, this class becomes the ancestor of all game entities. This base class usually contains virtual methods for core game functions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;GameObject&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;onEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Event&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything you author, from HUD widgets to hostile NPCs, subclasses one mega-type. Each instance magically inherits tick callbacks, draw hooks, and event plumbing. Convenient? Extremely. You get a uniform surface area "for free," plus a natural place to hang a central registry.&lt;/p&gt;

&lt;p&gt;The downside is inheritance sprawl: one mammoth base class fights composition, mixing orthogonal concerns into the same vtable. Want multiple reusable behaviors? You bolt more flags and overrides onto GameObject. Within a few milestones that base type balloons into hundreds of lines of virtual hooks.&lt;/p&gt;

&lt;p&gt;Bolting "components" onto the same hierarchy often compounds the mess instead of curing it. Eventually you regret the shape of the tree, yet countless shipped titles prove you can still finish under this pattern if scope stays modest.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;...ECS is good! But...&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This architectural model has exploded in popularity among indie developers and enthusiasts in recent years. The core idea is a radical separation of data and logic, built around three key concepts. An entity is just an identifier, with no logic or data of its own. A component is a container for a specific type of data, such as position, health, or sound parameters. A system is a functional block that processes components according to specific rules. None of them works alone, but together they replace traditional object hierarchies with batch-oriented data processing.&lt;/p&gt;

&lt;p&gt;For instance, a physics system can walk all entities that have both &lt;code&gt;Transform&lt;/code&gt; and &lt;code&gt;Velocity&lt;/code&gt; and update every moving object's coordinates in one structured pass. Benefits include strong performance from cache-friendly layouts, clearer separation of responsibilities between subsystems, and good scalability.&lt;/p&gt;

&lt;p&gt;Drawbacks include jumping straight into a fairly complex architecture that often needs a lot of boilerplate and patterns. Without specialized editors, ECS-heavy codebases can be hard to read, and without visual debugging tools, diagnosing issues gets painful. For smaller projects, it can feel like using a sledgehammer to crack a nut.&lt;/p&gt;

&lt;h2&gt;
  
  
  Game engine
&lt;/h2&gt;

&lt;p&gt;Maybe you should leave everything exactly as it is? Yes and no. The engine, and the scaffolding around it, is a means to an end. If you are hacking on a weekend hobby project, do not chase the perfect framework, or you may ship nothing but scaffolding while the actual game keeps slipping. Still, architecture matters the way a skeleton matters: nobody admires your ribs in screenshots, but if the bones are crooked, everything built on top aches, bends, and snaps under light stress. When the structure becomes genuinely painful, do not be precious about it. Throw it out and rebuild. Everyone tosses bad foundations sometimes (that is the spirit behind the "three systems" rule). Classics such as Jason Gregory's Game Engine Architecture remain relevant because nobody has handed us a strictly better substitute.&lt;/p&gt;

&lt;p&gt;To learn how games actually tick, you do not need an Unreal-scale codebase on day one. If you want to avoid becoming yet another résumé line that reads "Unreal C++" yet hides shallow familiarity with how containers or allocators behave, try shipping your first or second project with minimal middleware. Make something deliberately crude: a window, a handful of sprites, a tiny resource loader that stuffs textures into a &lt;code&gt;.zip&lt;/code&gt;. Call it a toy engine if you like: simple, buggy, full of reinvented wheels, but yours, and built while knowing what each lever does. Skip Unity, skip Godot, skip the polished shortcuts that quietly vault you past ninety percent of what is happening under the hood.&lt;/p&gt;

&lt;p&gt;You will fight architecture problems, patterns, and asset budgets head-on. It costs calendar time, but you earn more than a demo reel clip: you earn intuition about internals that is hard to fake in interviews. That is where serious growth starts, without borrowing momentum from black boxes. Someone who only knows editor wiring may stay boxed into one toolchain; someone who understands memory layouts, threading contracts, and asset pipelines can adapt across engines.&lt;/p&gt;

&lt;p&gt;That said, if Godot, Unreal, or another turnkey stack matches your patience and goals, use them. Ambition and pace matter more than purity contests. Even if you eventually standardize on third-party tech, the scars from rolling your own stack become leverage: you stop treating engines like magic and start reading them as engineered systems.&lt;/p&gt;

&lt;p&gt;As always, the choice is yours.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Author: Sergei Kushnirenko&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sergei has over 20-year experience in coding and game development. He graduated from ITMO National Research University and began his career developing software for naval simulators, navigation systems, and network solutions. For the past fifteen years, Sergei has specialized in game development: at Electronic Arts, he worked on optimizing The Sims and SimCity BuildIt, and at Gaijin Entertainment, Sergei headed up the porting of games to the Nintendo Switch and Apple TV platforms. Sergei actively participates in open-source projects, including the ImSpinner library and the Pharaoh (1999) game restoration project.&lt;/p&gt;

&lt;h2&gt;
  
  
  All parts
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/1361/" rel="noopener noreferrer"&gt;Game++. Part 1.1: C++, game engines, and architectures&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>gamedev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Let's make a programming language. Lexer—Key points</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Tue, 19 May 2026 13:54:45 +0000</pubDate>
      <link>https://forem.com/pvsdev/lets-make-a-programming-language-lexer-key-points-3ld0</link>
      <guid>https://forem.com/pvsdev/lets-make-a-programming-language-lexer-key-points-3ld0</guid>
      <description>&lt;p&gt;This is the third part in our series of talks on creating a programming language. The episode focuses on building a lexer—a fundamental component of a language interpreter responsible for breaking down input strings into atomic tokens.&lt;/p&gt;

&lt;h2&gt;
  
  
  About the speaker
&lt;/h2&gt;

&lt;p&gt;Yuri Minaev is an experienced C++ developer, architect at PVS-Studio, and a recognized voice in the C++ community who has spoken at CppCast, C++ on Sea, and CppCon. Over the course of ten sessions, he'll guide you through each stage of building your own programming language.&lt;/p&gt;

&lt;h2&gt;
  
  
  The lexer in action
&lt;/h2&gt;

&lt;p&gt;The speaker begins by revisiting grammars and describes how a lexer handles the lowest-level grammar elements like numbers, identifiers, operators, variable names, and keywords. Using simple binary expressions as examples, Yuri demonstrates how the lexer scans an input string character by character, groups symbols into tokens, and ignores whitespaces.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the lexer works in C++
&lt;/h2&gt;

&lt;p&gt;Yuri explains the lexer's internal design in C++, including the token structure, iterator-based scanning, and "lazy tokenization". Why is it "lazy"? Instead of handling the entire input at once, the lexer generates tokens on demand and supports token previewing through a cached token mechanism. The implementation uses &lt;code&gt;string_view&lt;/code&gt; to avoid unnecessary memory allocations and relies on helper functions to classify characters as digits, letters, separators, or operators.&lt;/p&gt;

&lt;p&gt;The talk also covers handling integers, floating-point numbers, identifiers, keywords, single-character operators, and multi-character operators such as &lt;code&gt;==&lt;/code&gt; and &lt;code&gt;!=&lt;/code&gt;. The lexer follows a greedy strategy and continues parsing even after encountering invalid input, producing error tokens rather than stopping execution.&lt;/p&gt;

&lt;p&gt;Yuri wraps up the session by discussing ambiguous grammar problems in languages like C++, explains why the custom language avoids them, and outlines plans to implement a parser in the next part.&lt;/p&gt;

&lt;h2&gt;
  
  
  Want more?
&lt;/h2&gt;

&lt;p&gt;If you want to watch other talks or see the whole episode, &lt;a href="https://pvs-studio.com/en/blog/video/11585/" rel="noopener noreferrer"&gt;follow this link.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also sign up for our upcoming webinars, for example: &lt;a href="https://pvs-studio.com/en/webinar/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=webinar&amp;amp;utm_content=recap" rel="noopener noreferrer"&gt;Let's make a programming language. Parser&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you'd like to learn more about PVS-Studio analyzer, check out our &lt;a href="https://pvs-studio.com/en/" rel="noopener noreferrer"&gt;website&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;See ya!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>cpp</category>
      <category>tutorial</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>PVS-Studio in CMake: It's official now!</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Mon, 18 May 2026 09:36:47 +0000</pubDate>
      <link>https://forem.com/pvsdev/pvs-studio-in-cmake-its-official-now-4bk3</link>
      <guid>https://forem.com/pvsdev/pvs-studio-in-cmake-its-official-now-4bk3</guid>
      <description>&lt;p&gt;If you're working on a cross-platform project in C or C++, you usually don't rely on a single build system, but instead use a build script generator. CMake, the most popular one, has recently been officially integrated with PVS-Studio static analyzer for these languages.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyy24jat9ltnjxmfqs2k2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyy24jat9ltnjxmfqs2k2.png" alt="1374_NativeInCMake/image1.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CMake is Kitware's flagship product for software developers. This is a project with a &lt;a href="https://cmake.org/history/" rel="noopener noreferrer"&gt;rich history&lt;/a&gt; that dates back almost as far as the company itself. The first version was released in &lt;a href="https://pvs-studio.com/en/blog/posts/cpp/1224/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1374" rel="noopener noreferrer"&gt;2000&lt;/a&gt;, about two years after the founding of Kitware.&lt;/p&gt;

&lt;p&gt;Over time, all of Kitware's projects (such as the &lt;a href="https://vtk.org/" rel="noopener noreferrer"&gt;Visualization Toolkit&lt;/a&gt; library and the &lt;a href="https://www.paraview.org/" rel="noopener noreferrer"&gt;ParaView&lt;/a&gt; engine based on it and designed to for interactive scientific visualization) began using CMake to define their project structure and build process. Other major open-source projects followed suit: KDE, LLVM, and Qt all replaced GNU Autoconf in CMake's favor at various times. PVS-Studio analyzer for C and C++ fully switched to CMake in early 2020.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;PVS-Studio can analyze projects regardless of the build system: on Windows, the analyzer &lt;a href="https://pvs-studio.com/en/docs/manual/0031/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1374" rel="noopener noreferrer"&gt;intercepts calls&lt;/a&gt; to the compiler and its start commands. &lt;a href="https://pvs-studio.com/en/docs/manual/6615/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1374#trace" rel="noopener noreferrer"&gt;Compilation tracing&lt;/a&gt; is available for GNU/Linux systems.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  How does it work?
&lt;/h2&gt;

&lt;p&gt;Starting with &lt;a href="https://cmake.org/cmake/help/latest/release/4.3.html" rel="noopener noreferrer"&gt;version 4.3.0&lt;/a&gt;, CMake can run PVS-Studio while compiling a C or C++ project. Analyzer warnings will appear alongside compiler messages and warnings.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4qoqxkowaadmzuz4lxxo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4qoqxkowaadmzuz4lxxo.png" alt="1374_NativeInCMake/image2.png" width="800" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Picture 1. The beginning of the build log file for the libcrypto component from LibreSSL 4.3.1 combined with the PVS-Studio analysis&lt;/p&gt;

&lt;p&gt;The process of configuring PVS-Studio static analyzer is almost identical to that of other solutions supported by CMake: simply declare the &lt;code&gt;CMAKE_&amp;lt;LANG&amp;gt;_PVS_STUDIO&lt;/code&gt; directive and &lt;a href="https://pvs-studio.com/en/docs/manual/6615/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1374#flags" rel="noopener noreferrer"&gt;list the parameters&lt;/a&gt; after it, just as if you were running &lt;code&gt;CompilerCommandsAnalyzer&lt;/code&gt; on Windows or &lt;code&gt;pvs-studio-analyzer&lt;/code&gt; on *nix systems. &lt;code&gt;&amp;lt;LANG&amp;gt;&lt;/code&gt; can take the &lt;code&gt;C&lt;/code&gt; and &lt;code&gt;CXX&lt;/code&gt; values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CMAKE_C_PVS_STUDIO&lt;/span&gt; &lt;span class="n"&gt;CompilerCommandsAnalyzer&lt;/span&gt; &lt;span class="n"&gt;analyze&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;GA&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CMAKE_CXX_PVS_STUDIO&lt;/span&gt; &lt;span class="n"&gt;CompilerCommandsAnalyzer&lt;/span&gt; &lt;span class="n"&gt;analyze&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;GA&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can place this directive at any level in &lt;code&gt;CMakeLists.txt&lt;/code&gt;, controlling how much code the analyzer checks.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We &lt;a href="https://pvs-studio.com/en/blog/posts/cpp/1277/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1374" rel="noopener noreferrer"&gt;checked&lt;/a&gt; the CMake 4.1 source code in August 2025. PVS-Studio analyzer for C and C++ detected many interesting things there.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Using the built-in integration to analyze code limits your options for interacting with the analysis results: the PVS-Studio report is not saved, since source code files are analyzed individually. So, the report conversion via &lt;code&gt;plog-converter&lt;/code&gt; is unavailable, but you can aggregate analyzer warnings in &lt;a href="https://www.cdash.org/" rel="noopener noreferrer"&gt;CDash&lt;/a&gt;—a test result monitoring system also developed by Kitware. The developers on the CMake team did just that—you can see the result of the integration &lt;a href="https://open.cdash.org/builds/10775569" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's put it into practice
&lt;/h2&gt;

&lt;p&gt;We'll go over the analysis process using the example of the &lt;a href="https://www.libressl.org/" rel="noopener noreferrer"&gt;LibreSSL&lt;/a&gt; cryptographic library, which is a hard fork of OpenSSL designed to improve the codebase quality, security, and maintenance. The examples of command-line commands are written for Windows.&lt;/p&gt;

&lt;p&gt;Open the root &lt;code&gt;CMakeLists.txt&lt;/code&gt; file and add the following line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CMAKE_C_PVS_STUDIO&lt;/span&gt; &lt;span class="n"&gt;CompilerCommandsAnalyzer&lt;/span&gt; &lt;span class="n"&gt;analyze&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="s"&gt;"GA\;OP"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, generate files for the Ninja build system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;cmake&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;G&lt;/span&gt; &lt;span class="n"&gt;Ninja&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, run any build target, such as &lt;code&gt;libtls&lt;/code&gt;—a new version of the &lt;code&gt;libssl&lt;/code&gt; library for TLS connections:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;cd&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;
&lt;span class="n"&gt;ninja&lt;/span&gt; &lt;span class="n"&gt;tls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The build starts, and the analysis begins.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fryb6y3hytbe60md8soj6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fryb6y3hytbe60md8soj6.png" alt="1374_NativeInCMake/image3.png" width="800" height="325"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Picture 2. The head of the build log file for the libtls component from LibreSSL 4.3.1 combined with the PVS-Studio analysis&lt;/p&gt;

&lt;p&gt;PVS-Studio warnings are displayed in an easy-to-read format: the path to the file with the line number, the diagnostic rule number, and its description. Let's take a look at some warnings from the &lt;code&gt;libcrypto&lt;/code&gt; cryptographic library used in &lt;code&gt;libtls&lt;/code&gt;:&lt;/p&gt;

&lt;h3&gt;
  
  
  Some trickery
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="nf"&gt;BF_ecb_encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;BF_KEY&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;encrypt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;BF_LONG&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="n"&gt;n2l&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;n2l&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;encrypt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;BF_encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="n"&gt;BF_decrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="n"&gt;l2n&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="n"&gt;l2n&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;              &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;PVS-Studio warning: V1001 The 'l' variable is assigned but is not used by the end of the function. blowfish.c 587&lt;/p&gt;

&lt;p&gt;Here's a simple and straightforward Blowfish algorithm. In this case, the data buffer is quickly flushed for encryption or decryption, depending on the value of &lt;code&gt;encrypt&lt;/code&gt;. However, the data won't be overwritten if the app was &lt;a href="https://godbolt.org/z/TbaG5Es4M" rel="noopener noreferrer"&gt;compiled with optimization enabled&lt;/a&gt;, and the 12 bytes—8 of which are a data block—will remain in memory.&lt;/p&gt;

&lt;h3&gt;
  
  
  You're repeating yourself. You're repeating yourself.
&lt;/h3&gt;

&lt;p&gt;To read information from X.509 certificates and similar documents, the Abstract Syntax Notation Once (ASN.1) parser is required.&lt;/p&gt;

&lt;p&gt;PVS-Studio warning: V501 There are identical sub-expressions '(c == ' ')' to the left and to the right of the '||' operator. a_print.c 77:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="nf"&gt;ASN1_PRINTABLE_type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sc"&gt;'\0'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;(((&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="sc"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="sc"&gt;'z'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
        &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="sc"&gt;'A'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="sc"&gt;'Z'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;                   &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
        &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="sc"&gt;'0'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="sc"&gt;'9'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;'\''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;    &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;'('&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;')'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;'+'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;','&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;'-'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;'.'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;'/'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;':'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;'='&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;'?'&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
      &lt;span class="n"&gt;ia5&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mh"&gt;0x80&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;t61&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We'll stretch it out a bit by placing the conditions in &lt;code&gt;if&lt;/code&gt; in a single column:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="sc"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="sc"&gt;'z'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="sc"&gt;'A'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="sc"&gt;'Z'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                   &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
    &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="sc"&gt;'0'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="sc"&gt;'9'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                   &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
    &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;'\''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here's the sneaky duplicate space check. We believe this is purely a coincidence :)&lt;/p&gt;

&lt;p&gt;You can remove it from any part of the condition without losing any functionality:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;(((&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="sc"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="sc"&gt;'z'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="sc"&gt;'A'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="sc"&gt;'Z'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
    &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="sc"&gt;'0'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="sc"&gt;'9'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;'\''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;'('&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;')'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;'+'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;','&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;'-'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;'.'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;'/'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;':'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;'='&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;'?'&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;More complex cases involving repeated checks within a condition also exist. To prevent this, you can use &lt;a href="https://pvs-studio.com/en/blog/terms/7003/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1374" rel="noopener noreferrer"&gt;table-style code formatting&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Will the old analysis options remain?
&lt;/h2&gt;

&lt;p&gt;The familiar ways of analyzing CMake projects using &lt;code&gt;compile_commands.json&lt;/code&gt; and the CMake module haven't gone anywhere—you can still use them. You can find more details in our &lt;a href="https://pvs-studio.com/en/docs/manual/6591/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1374" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;. Keeping your code bug-free has become even easier, and we hope that integrating static analysis into your development pipeline will be just as easy! If you'd like to try out the new integration now, you can request a free &lt;a href="https://pvs-studio.com/en/pvs-studio/try-free/?utm_source=website&amp;amp;utm_medium=devto&amp;amp;utm_campaign=article&amp;amp;utm_content=1374" rel="noopener noreferrer"&gt;trial license&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>cpp</category>
    </item>
    <item>
      <title>Static code analysis and software time to market</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Fri, 15 May 2026 14:06:43 +0000</pubDate>
      <link>https://forem.com/pvsdev/static-code-analysis-and-software-time-to-market-43fe</link>
      <guid>https://forem.com/pvsdev/static-code-analysis-and-software-time-to-market-43fe</guid>
      <description>&lt;p&gt;This article focuses on the methodology of static code analysis and its role in streamlining the time to market for software products. Let's think about how relevant it is to ask about the value of static analysis. We'll explore how it works alongside other software quality assurance practices. Integrating static analysis into the development process is not an overhead—it's an investment that pays for itself through early defect detection.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ml3gtvr8dz1xyhuvep4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ml3gtvr8dz1xyhuvep4.png" alt="1373_Time_to_market/image1.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How static analysis speeds up time to market
&lt;/h2&gt;

&lt;p&gt;You might have heard the question: "How does static analysis get a product to market faster?". Phrased like that, the answer is disappointing: static analysis by itself does not speed up market entry—it takes time to introduce static analysis and handle warnings. But the real issue is that the question itself is flawed—much like asking whether the testing phase speeds up a product release.&lt;/p&gt;

&lt;p&gt;The right question to ask is: "How does static analysis reduce time to market when shipping products at a given level of quality and reliability?". This framing reveals the methodology's core value.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Counter-intuitively, adding quality checks accelerates development cycles rather than slowing them down. When developers have confidence that their changes won't break architectural constraints or introduce subtle bugs, they can work more boldly and efficiently" [&lt;a href="https://www.qt.io/software-insights/the-hidden-roi-of-static-code-analysis-and-architecture-verification" rel="noopener noreferrer"&gt;1&lt;/a&gt;]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why the quick approach is flawed
&lt;/h2&gt;

&lt;p&gt;The testing analogy is particularly telling. No one asks whether testing speeds up a product release—everyone understands it's a necessary quality assurance step. Yet, in theory, the fastest way to launch a product is to write some working code and deploy it to production right away.&lt;/p&gt;

&lt;p&gt;But in practice, nobody even thinks about shortening the testing phase. More often, we see that testing alone isn't enough.&lt;/p&gt;

&lt;p&gt;According to the research, poor software quality costs the US economy over $2 trillion annually [&lt;a href="https://www.it-cisq.org/the-cost-of-poor-quality-software-in-the-us-a-2022-report/" rel="noopener noreferrer"&gt;2&lt;/a&gt;]. In such projects, up to 50% of effort goes into fixing bugs instead of creating business value [&lt;a href="https://www.betabreakers.com/blog/software-survival-in-2024-understanding-2023-project-failure-statistics-and-the-role-of-quality-assurance/" rel="noopener noreferrer"&gt;3&lt;/a&gt;].&lt;/p&gt;

&lt;h2&gt;
  
  
  Economics of bug detection: the earlier, the cheaper
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz2ogb0gq1wy85n7dttlu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz2ogb0gq1wy85n7dttlu.png" alt="1373_Time_to_market/image2.png" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Figure 1. According to IBM System Science Institute — Relative cost of fixing defects.&lt;/p&gt;

&lt;p&gt;The exponential growth in the cost of fixing a defect at later development stages is the key principle that explains the value of static analysis. According to the IBM Systems Science Institute, fixing a bug during testing might cost 2–3 times more than fixing it at the implementation (coding) stage. After the release, fixing that same bug costs 6 times more than during testing, and 15 times more than during implementation [&lt;a href="https://www.functionize.com/blog/the-cost-of-finding-bugs-later-in-the-sdlc?trk=article-ssr-frontend-pulse_little-text-block" rel="noopener noreferrer"&gt;4&lt;/a&gt;].&lt;/p&gt;

&lt;p&gt;Static analysis runs during the implementation stage—right when developers write code. It helps eliminate many errors before they even get to the build system, long before testing or production. Automated tools check for typos, control-flow anomalies, buffer overflows, and other defects without requiring test scenarios.&lt;/p&gt;

&lt;h2&gt;
  
  
  Static analysis does not replace other methods—it complements them
&lt;/h2&gt;

&lt;p&gt;Static analysis is no silver bullet, nor does it aim to replace other quality assurance methods. Integrating it into the development life cycle improves software quality, security, and reliability. This way, static analysis shortens development time through early bug detection. However, the most effective approach combines several complementary methods.&lt;/p&gt;

&lt;p&gt;Experienced developers don't pick a single approach; they leverage a whole toolkit: static analysis, unit testing, dynamic analysis, composition analysis, manual testing, and more. The synergy of using different techniques together catches a broad range of defects before the release.&lt;/p&gt;

&lt;p&gt;Experts estimate that most testing methods find around 35% of software defects [5]. This reinforces the need for a multi-level approach, in which static analysis detects those categories of errors that are difficult or impossible to find using other methods.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-life cases and measurable results
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fue6c4snxqi3h1ctvptcb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fue6c4snxqi3h1ctvptcb.png" alt="1373_Time_to_market/image3.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Figure 2. Static Application Security Testing (SAST) makes it possible to focus more on building new features rather than on bugs and vulnerabilities.&lt;/p&gt;

&lt;p&gt;The usefulness of static analysis has been proven in practice by large companies. After adopting static analysis for mobile device development, Motorola halved the number of bugs that users discovered during alpha and beta testing [&lt;a href="https://www.perforce.com/customers/case-studies/kw/motorola" rel="noopener noreferrer"&gt;6&lt;/a&gt;].&lt;/p&gt;

&lt;p&gt;Once a team has spent 50 hours tracking down a bug that the analyzer could have caught right at the start [&lt;a href="https://pvs-studio.com/en/blog/posts/cpp/0221/" rel="noopener noreferrer"&gt;7&lt;/a&gt;].&lt;/p&gt;

&lt;p&gt;Research shows that development teams adopting DevSecOps practices with static analysis fix defects 11.5 times faster than those without such practices [&lt;a href="https://securityboulevard.com/2018/12/carnegie-mellons-software-engineering-institute-report-shows-efficacy-of-static-application-security-testing/" rel="noopener noreferrer"&gt;8&lt;/a&gt;]. Also, implementing static analysis tools doesn't add to the development workload to teams before the release. As developers become more skilled, the false-positive rate drops thanks to cleaner code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Applying the Shift Left approach
&lt;/h2&gt;

&lt;p&gt;Static analysis is a key component of the &lt;a href="https://pvs-studio.com/en/blog/terms/7013/" rel="noopener noreferrer"&gt;Shift Left&lt;/a&gt; approach, in which quality checks are moved to earlier stages of development. Implementing static analysis into the CI/CD pipeline enables fixing issues straight away, rather than days or weeks later.&lt;/p&gt;

&lt;p&gt;This automates most of the work involved in ensuring compliance with coding standards (MISRA C/C++, SEI CERT, OWASP ASVS) and frees up development time for higher-priority tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  ROI
&lt;/h2&gt;

&lt;p&gt;Implementing static analysis involves costs: purchasing tools, training the team, and integrating the process, yet these investments pay off. Static analysis tools spot potential vulnerabilities and bugs at a stage when fixing them remains cheap.&lt;/p&gt;

&lt;p&gt;Industry research highlights that the ROI from static analysis goes beyond prevented defects and faster regulatory compliance. It also gives teams confidence that they can keep developing the product with a low bug rate [&lt;a href="https://www.qt.io/software-insights/the-hidden-roi-of-static-code-analysis-and-architecture-verification" rel="noopener noreferrer"&gt;1&lt;/a&gt;]. This matters greatly for large-scale projects with a large amount of legacy code. &lt;/p&gt;

&lt;h2&gt;
  
  
  PVS-Studio tool as an example
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkze06jas1w2s52x6knwi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkze06jas1w2s52x6knwi.png" alt="1373_Time_to_market/image4.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Figure 3. PVS-Studio. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://pvs-studio.com/en/" rel="noopener noreferrer"&gt;PVS-Studio&lt;/a&gt; is a static code analyzer for C, C++, C#, Java, Go, JavaScript, and TypeScript.&lt;/p&gt;

&lt;p&gt;The tool is a classic example of a tool that accelerates the release of high-quality software. By integrating with IDEs and CI/CD systems, PVS-Studio catches bugs and potential vulnerabilities early, saving both budget and time.&lt;/p&gt;

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

&lt;p&gt;Adopting static analysis tools takes resources. Yet asking whether it speeds up time to market without considering quality misses the point. If the goal is simply to ship a product as fast as possible, the quickest route would indeed be to skip all checks.&lt;/p&gt;

&lt;p&gt;But when the goal is to deliver a high-quality, reliable, and secure product, static analysis becomes an essential tool for ensuring both quality and security. Using static analysis tools enables you to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;find errors early, when the cost to fix them is lowest;&lt;/li&gt;
&lt;li&gt;reduce the risk of vulnerabilities surfacing in production, which can lead to significant financial and reputational damage;&lt;/li&gt;
&lt;li&gt;automate standards compliance checks and lighten the team's workload;&lt;/li&gt;
&lt;li&gt;focus on high-level logic and architectural decisions during code reviews, rather than on looking for typos and other low-level defects;&lt;/li&gt;
&lt;li&gt;increase the stability of both new feature development and changes to legacy code;&lt;/li&gt;
&lt;li&gt;speed up time to market by cutting down unforeseen delays from fixing defects found late in the cycle.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, a static analyzer is a tool that speeds up development while raising quality. Just like testing, static analysis has become an essential part of professional software development. Its value lies in making the process predictable and the outcome aligned with business and user expectations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Julia Probst. &lt;a href="https://www.qt.io/software-insights/the-hidden-roi-of-static-code-analysis-and-architecture-verification" rel="noopener noreferrer"&gt;The Hidden ROI of Static Code Analysis and Architecture Verification&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Herb Krasner. New research: &lt;a href="https://www.it-cisq.org/the-cost-of-poor-quality-software-in-the-us-a-2022-report/" rel="noopener noreferrer"&gt;The cost of poor software quality in the US: A 2022 report&lt;/a&gt;. &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.betabreakers.com/blog/software-survival-in-2024-understanding-2023-project-failure-statistics-and-the-role-of-quality-assurance/" rel="noopener noreferrer"&gt;Software Survival in 2024: Understanding 2023 Project Failure Statistics and the Role of Quality Assurance&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Tamas Cser. &lt;a href="https://www.functionize.com/blog/the-cost-of-finding-bugs-later-in-the-sdlc?trk=article-ssr-frontend-pulse_little-text-block" rel="noopener noreferrer"&gt;The Cost of Finding Bugs Later in the SDLC&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Steve McConnell. Code complete. See the chapter 20.3 "Relative Effectiveness of Quality Techniques".&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.perforce.com/customers/case-studies/kw/motorola" rel="noopener noreferrer"&gt;Large-scale Deployment of Static Analysis Leads to Measurable Productivity and Quality Improvements&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Alexander Lotokhov. &lt;a href="https://pvs-studio.com/en/blog/posts/cpp/0221/" rel="noopener noreferrer"&gt;A User's Experience of Working with the Analyzer&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://securityboulevard.com/2018/12/carnegie-mellons-software-engineering-institute-report-shows-efficacy-of-static-application-security-testing/" rel="noopener noreferrer"&gt;Carnegie Mellon's Software Engineering Institute Report Shows Efficacy of Static Application Security Testing&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>marketing</category>
      <category>softwaredevelopment</category>
      <category>product</category>
      <category>devops</category>
    </item>
    <item>
      <title>Error handling in Go: Common pitfalls</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Fri, 08 May 2026 11:10:11 +0000</pubDate>
      <link>https://forem.com/pvsdev/error-handling-in-go-common-pitfalls-57j3</link>
      <guid>https://forem.com/pvsdev/error-handling-in-go-common-pitfalls-57j3</guid>
      <description>&lt;p&gt;Developers coming to Go from languages that use try/catch constructs, like Java or C#, may feel a bit turned around. The inner voice suggests using 'recover' with 'defer' as the nearest equivalent, but that's considered bad practice. This article covers why, and looks at common error-handling mistakes in Go. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foapriw1fpy9wfq4nnoqs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foapriw1fpy9wfq4nnoqs.png" alt="1371_Error_Handling_Issue/image1.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;The idea for this article came up spontaneously. Error handling in Go is already well covered, so I wasn't planning to rehash the same points.&lt;/p&gt;

&lt;p&gt;But things changed while I was building diagnostic rules for PVS-Studio's new Go analyzer. Testing them on real open-source projects, I kept running into the same error-handling mistakes. &lt;/p&gt;

&lt;p&gt;We've &lt;a href="https://ttps:/pvs-studio.com/en/blog/posts/go/1342/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1371" rel="noopener noreferrer"&gt;written before&lt;/a&gt; about how we test the analyzer on large projects from GitHub, but this time, the findings were interesting enough to deserve their own article. Hopefully it saves someone a headache. But first, here's a quick refresher on how error handling works in Go, and the reasoning behind it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common approach to error handling in Go
&lt;/h2&gt;

&lt;p&gt;Leaving out &lt;code&gt;try catch&lt;/code&gt; wasn't an oversight—it was a deliberate design decision. The authors believe that tying error handling to that control structure makes code more convoluted. It also pushes developers to treat plain errors as exceptions. You can read more about this &lt;a href="https://go.dev/doc/faq#exceptions" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Take a program that opens a file and modifies it. Various scenarios are possible: a file might exist or might not. Treating a missing file as an exception feels wrong.&lt;/p&gt;

&lt;p&gt;Go follows a simple principle: &lt;a href="https://go.dev/blog/errors-are-values" rel="noopener noreferrer"&gt;an error is a value&lt;/a&gt;. It's an ordinary value that a function returns explicitly, and the caller must explicitly handle it. Look at the example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// error handling&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first glance the code looks verbose, and it's obviously &lt;a href="https://en.wikipedia.org/wiki/Boilerplate_code" rel="noopener noreferrer"&gt;boilerplate&lt;/a&gt;. But the upside is that the control flow remains transparent, and the program is easy to read from top to bottom.&lt;/p&gt;

&lt;p&gt;But then why do we need &lt;code&gt;panic&lt;/code&gt; and &lt;code&gt;recover&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;In Go, &lt;code&gt;panic&lt;/code&gt; is a sign of that something went unexpectedly wrong. In ways that should never happen in correct code: an out-of-bounds slice index, dereferencing a nil pointer, and so on. The &lt;code&gt;recover&lt;/code&gt; mechanism lets us intercept a &lt;code&gt;panic&lt;/code&gt; before it brings the whole program down. But using it as try/catch substitute goes against Go idioms and conventions. &lt;/p&gt;

&lt;p&gt;That said, catching a &lt;code&gt;panic&lt;/code&gt; does have its place. The most common approach is at package or goroutine boundaries, so that a &lt;code&gt;panic&lt;/code&gt; doesn't crash the entire program:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;encodeState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;marshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;opts&lt;/span&gt; &lt;span class="n"&gt;encOpts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;recover&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;je&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.(&lt;/span&gt;&lt;span class="n"&gt;jsonError&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;je&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}()&lt;/span&gt;
  &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reflectValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reflect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ValueOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This example comes from the standard &lt;code&gt;json&lt;/code&gt; package, specifically the &lt;a href="https://go.dev/src/encoding/json/encode.go" rel="noopener noreferrer"&gt;&lt;code&gt;encode.go&lt;/code&gt;&lt;/a&gt; file. Here, if a &lt;code&gt;panic&lt;/code&gt; unwinds the stack up to the top-level function call, the program recovers and returns an expected error value. &lt;/p&gt;

&lt;p&gt;So &lt;code&gt;recover&lt;/code&gt; is meant to prevent crashes, not to handle business logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to make mistakes when handling errors
&lt;/h2&gt;

&lt;p&gt;So, in Go errors are stored in a variable and checked against &lt;code&gt;nil&lt;/code&gt;. It seems simple, but even this straightforward approach leaves room for mistakes. As an example, let's look at the &lt;a href="https://github.com/hashicorp/vault" rel="noopener noreferrer"&gt;vault&lt;/a&gt; project—an open-source tool for managing sensitive data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Core&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;PersistTOTPKey&lt;/span&gt;&lt;span class="p"&gt;(....)&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;ks&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;totpKey&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;Key:&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;jsonutil&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EncodeJSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;barrier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;logical&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StorageEntry&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;Key:&lt;/span&gt;   &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(....),&lt;/span&gt;
    &lt;span class="nl"&gt;Value:&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v8014/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1371" rel="noopener noreferrer"&gt;V8014&lt;/a&gt; Two 'if' statements have identical conditions. The first 'if' statement contains function return, making the second 'if' redundant, or the code contains a logical error. &lt;a href="https://github.com/hashicorp/vault/blob/d73581e2356f73d0138b06da2e66ce5ebfdf1a0a/vault/login_mfa.go#L1099" rel="noopener noreferrer"&gt;login_mfa.go 1099&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this snippet, the error from &lt;code&gt;jsonutil.EncodeJSON(ks)&lt;/code&gt; is checked. Then, the same error is checked again in the next condition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;barrier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;logical&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StorageEntry&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;Key:&lt;/span&gt;   &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(....),&lt;/span&gt;
        &lt;span class="nl"&gt;Value:&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clearly, there's no point in checking the same error twice. Besides, if &lt;code&gt;errl != nil&lt;/code&gt; is true, the method will return. The developer most likely intended to capture a value from &lt;code&gt;Put&lt;/code&gt; and check it. What's more, the &lt;code&gt;Put&lt;/code&gt; method returns an error value that is worth checking:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Storage&lt;/span&gt; &lt;span class="n"&gt;interface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
  &lt;span class="n"&gt;Put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;StorageEntry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, the fix might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;jsonutil&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EncodeJSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;barrier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;logical&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StorageEntry&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;Key:&lt;/span&gt;   &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(....),&lt;/span&gt;
  &lt;span class="nl"&gt;Value:&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second &lt;code&gt;if&lt;/code&gt; block checks the error that &lt;code&gt;Put&lt;/code&gt; returns.&lt;/p&gt;

&lt;p&gt;In the &lt;a href="https://github.com/FerretDB/FerretDB/" rel="noopener noreferrer"&gt;FerretDB&lt;/a&gt; project, which is an alternative to MongoDB, we spot a similar one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;msgKillCursors&lt;/span&gt;&lt;span class="p"&gt;(....)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
  &lt;span class="n"&gt;cursorsV&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;getRequiredParamAny&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"cursors"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;curArr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;cursorsV&lt;/span&gt;&lt;span class="p"&gt;.(&lt;/span&gt;&lt;span class="n"&gt;wirebson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AnyArray&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;                                             &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
    &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(....)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lazyerrors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(....)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;cursors&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;curArr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Decode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;                                             &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lazyerrors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v8014/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1371" rel="noopener noreferrer"&gt;V8014&lt;/a&gt; Two 'if' statements have identical conditions. The first 'if' statement contains function return, making the second 'if' redundant, or the code contains a logical error. &lt;a href="https://github.com/FerretDB/FerretDB/blob/799235dab9e350655e72e65a0b24d849f7d68143/internal/handler/msg_killcursors.go#L61" rel="noopener noreferrer"&gt;msg_killcursors.go 61&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The value of the &lt;code&gt;err&lt;/code&gt; variable changes here. But instead, the code checks twice if the &lt;code&gt;cursorsV&lt;/code&gt; variable is cast to the &lt;code&gt;wirenson.AnyArray&lt;/code&gt; type. Most likely, the second &lt;code&gt;!ok&lt;/code&gt; was a mistake, and the code should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;cursors&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;curArr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Decode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lazyerrors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is another piece of code that accidentally re-checks the same error, now in &lt;a href="https://github.com/lxc/incus" rel="noopener noreferrer"&gt;Incus&lt;/a&gt;—a manager for virtual machines.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;proxy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;deviceConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RunConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
  &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pidPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Kill Process if started, but could not save the file&lt;/span&gt;
    &lt;span class="n"&gt;err2&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Stop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"....: %s: %s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"....: %w"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v8020/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1371" rel="noopener noreferrer"&gt;V8020&lt;/a&gt; Recurring check. The 'err != nil' condition was already verified on line 407 &lt;a href="https://github.com/lxc/incus/blob/321c40f963e9c1e7b68736fb4941431cccac3d60/internal/server/device/proxy.go#L407" rel="noopener noreferrer"&gt;proxy.go 407&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The second condition should obviously check &lt;code&gt;err2&lt;/code&gt; instead of &lt;code&gt;err&lt;/code&gt;—&lt;code&gt;err&lt;/code&gt; has already been checked and hasn't changed since. Also, &lt;code&gt;err2&lt;/code&gt; appears in the error handling:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"....: %s: %s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, it makes sense to check it too. PVS-Studio flagged 65 warning of this type in the open-source platform &lt;a href="https://github.com/rancher/rancher" rel="noopener noreferrer"&gt;Rancher&lt;/a&gt;—more than anywhere else:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;MachineClient&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;ListAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;opts&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;types&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ListOpts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(....)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;MachineCollection&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; 
    &lt;span class="n"&gt;next&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;...)&lt;/span&gt;
    &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;next&lt;/span&gt;
    &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v8014/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1371" rel="noopener noreferrer"&gt;V8014&lt;/a&gt; Two 'if' statements have identical conditions. The first 'if' statement contains function return, making the second 'if' redundant, or the code contains a logical error. &lt;a href="https://github.com/rancher/rancher/blob/ec043c0cdf36b6bfe8ebc938c24af878a7a76d20/pkg/client/generated/cluster/v1beta2/zz_generated_cluster.x-k8s.io.machine.go#L113" rel="noopener noreferrer"&gt;zz_generated_cluster.x-k8s.io.machine.go 113&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This one is tricky precisely because it looks right: the loop iterates as long as &lt;code&gt;next != nil&lt;/code&gt; and &lt;code&gt;err == nil&lt;/code&gt;, then check &lt;code&gt;err != nil&lt;/code&gt; after the loop. But there's a catch. &lt;/p&gt;

&lt;p&gt;The analyzer points out that the &lt;code&gt;err&lt;/code&gt; used inside the loop is not the same &lt;code&gt;err&lt;/code&gt; that is checked after it. The &lt;code&gt;err&lt;/code&gt; checked after the loop is the original error from the earlier declaration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the loop terminates because &lt;code&gt;err != nil&lt;/code&gt;, we'd want to output that error. Instead, the code will return the error from the earlier declaration. &lt;/p&gt;

&lt;p&gt;The fix is easy: check &lt;code&gt;err&lt;/code&gt; inside the loop and return early. This way, the method returns the error that actually caused the iteration to stop.  &lt;/p&gt;

&lt;p&gt;The number of repeated warnings is easy to explain: many types require the same code with minor changes, so the old code gets copied along with all its bugs.&lt;/p&gt;

&lt;p&gt;I got curious and traced the origins of this code, which lead me to this &lt;a href="https://github.com/rancher/rancher/commit/3e5ab6a7baf58a2d63d1f07b9bdeb79b2c7d3875" rel="noopener noreferrer"&gt;commit&lt;/a&gt;. It adds a whopping 307,251 lines of code, and the comment "Add generated code" settles it. The bug was introduced and then spread across the entire project.&lt;/p&gt;

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

&lt;p&gt;What's the takeaway for today? Go is unquestionably clearer and more explicit about error handling. Still, it's possible to slip up—as the examples from open-source GitHub projects show that. Even in large and popular projects (some have over 30,000 stars), some very ordinary errors persist.&lt;/p&gt;

&lt;p&gt;This is a good reminder that no codebase is too big or too well-known to benefit from an extra set of eyes. That's where a static analyzer comes in handy.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We've recently launched the beta test for the new PVS-Studio analyzers coming. You are welcome to join it &lt;a href="https://pvs-studio.com/en/pvs-studio-eap/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1371" rel="noopener noreferrer"&gt;here&lt;/a&gt;! The EAP is available for JavaScript, TypeScript, and Go.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Take care of yourself and your code!&lt;/p&gt;

</description>
      <category>go</category>
      <category>development</category>
    </item>
    <item>
      <title>Building a programming language live: it’s time for the parser</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Thu, 07 May 2026 15:05:37 +0000</pubDate>
      <link>https://forem.com/pvsdev/building-a-programming-language-live-its-time-for-the-parser-2f3l</link>
      <guid>https://forem.com/pvsdev/building-a-programming-language-live-its-time-for-the-parser-2f3l</guid>
      <description>&lt;p&gt;Ever wondered how a parser works? Good news: in this session, we’ll cover exactly that, and build our own expression parser live.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Felp8kr5vvdyayd9rj17n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Felp8kr5vvdyayd9rj17n.png" alt=" " width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://pvs-studio.com/en/webinar/28/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=webinar&amp;amp;utm_content=web4" rel="noopener noreferrer"&gt;Join the new webinar: Let’s make a programming language. Parser on May 21&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Previously, we implemented a lexer: the component that takes raw input and turns it into a sequence of tokens. The recording of that session is coming soon to &lt;a href="https://pvs-studio.com/en/blog/video/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=webinar&amp;amp;utm_content=web4" rel="noopener noreferrer"&gt;our website&lt;/a&gt; and &lt;a href="https://www.youtube.com/@PVSStudio_channel?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=webinar&amp;amp;utm_content=web4" rel="noopener noreferrer"&gt;YouTube channel&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The parser takes that stream of tokens and gives it structure. This is where the grammar of your language really comes to life (if you missed our session on grammars, you can check it out &lt;a href="https://pvs-studio.com/en/blog/video/11644/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=webinar&amp;amp;utm_content=web4" rel="noopener noreferrer"&gt;here&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;In our experience, every parser starts with one thing: parsing expressions — so that’s exactly where we’ll begin. We’ll explain what a parser is, walk through the recursive descent approach, and show how to build your own expression parser step by step.&lt;/p&gt;

&lt;p&gt;Our speaker, &lt;strong&gt;Yuri Minaev&lt;/strong&gt;, is an experienced C++ developer and static analyzer architect at PVS-Studio. He’s hosted every session in the series and is always happy to answer questions on language design along the way. Don’t hesitate to ask online!&lt;/p&gt;

&lt;p&gt;This series is aimed at developers who want to go beyond just using languages and start understanding how they’re built. Whether you’ve been with us from the beginning or are jumping in now, this is a great place to start.&lt;/p&gt;

&lt;p&gt;If you missed any of the previous sessions, don’t worry. All registered participants get access to the recordings. You can also catch up on YouTube or the PVS-Studio website.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pvs-studio.com/en/blog/video/11585/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=webinar&amp;amp;utm_content=web4" rel="noopener noreferrer"&gt;First talk: Let’s make a programming language. Intro&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pvs-studio.com/en/blog/video/11644/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=webinar&amp;amp;utm_content=web4" rel="noopener noreferrer"&gt;Second talk: Let’s make a programming language. Grammars&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Register now to join us live, ask your questions, and get the most out of the session. Don’t miss the chance to build your own language alongside an experienced developer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://pvs-studio.com/en/webinar/28/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=webinar&amp;amp;utm_content=web4" rel="noopener noreferrer"&gt;Join the webinar — Let’s make a programming language. Parser on May 21&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;P.S. Don’t forget to check your inbox and confirm your registration!&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>languagedesign</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>What's new in Java 26</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Tue, 05 May 2026 11:20:38 +0000</pubDate>
      <link>https://forem.com/pvsdev/whats-new-in-java-26-3anf</link>
      <guid>https://forem.com/pvsdev/whats-new-in-java-26-3anf</guid>
      <description>&lt;p&gt;Java keeps evolving! Java 26 is out. The release brings many features aimed at optimizing Java applications and drops support for applets. We cover all of this and more below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ficwbqazwboq6q1q80lm0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ficwbqazwboq6q1q80lm0.png" alt="1370_java26/image1.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Currently, Java ships a new version every six months. The last release was Java 25 in September 2025, so March 2026 meant it was time for Java 26.&lt;/p&gt;

&lt;p&gt;Java 25 was an LTS release; this version, however, isn't designed for long-term support. The new version didn't add as many features as the previous one, but it brought important changes to the language. After all, it's not about quantity :)&lt;/p&gt;

&lt;p&gt;So, what's new in Java 26?&lt;/p&gt;

&lt;h2&gt;
  
  
  JEP 500 Prepare to Make Final Mean Final
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://openjdk.org/jeps/500" rel="noopener noreferrer"&gt;JEP&lt;/a&gt; link.&lt;/p&gt;

&lt;p&gt;A curious name. What does it mean, though? Here's some background info.&lt;/p&gt;

&lt;p&gt;Starting with JDK 5, we can use reflection to change the value of &lt;code&gt;final&lt;/code&gt; fields (&lt;code&gt;java.lang.reflect#setAccessible&lt;/code&gt; and &lt;code&gt;java.lang.reflect#set&lt;/code&gt;). Handy for those who need it (but how often do you modify &lt;code&gt;final&lt;/code&gt; fields?). Either way, it's not ideal for two other reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;When working with the &lt;code&gt;final&lt;/code&gt; field, you expect the primitive object to never change after initialization. But with reflection in the picture, the specs and the actual behavior don't match up.&lt;/li&gt;
&lt;li&gt;You can't perform optimizations on &lt;code&gt;final&lt;/code&gt; fields. &lt;a href="https://en.wikipedia.org/wiki/Constant_folding" rel="noopener noreferrer"&gt;Constant folding&lt;/a&gt; is impossible if there's any chance the value or expression in the constant could change.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To eliminate inconsistencies and enable optimization for everything related to &lt;code&gt;final&lt;/code&gt; fields, starting with this JEP, developers will gradually lose the option to modify them. How?&lt;/p&gt;

&lt;p&gt;In Java 26, the JVM will issue special warnings when the &lt;code&gt;final&lt;/code&gt; value is changed. In future versions, attempting to modify the &lt;code&gt;final&lt;/code&gt; field will result in an exception.&lt;/p&gt;

&lt;p&gt;This approach gives developers time to adapt their applications and libraries to the change. The JVM, on the other hand, will have room for optimization. Also, there will be more consistency for &lt;code&gt;final&lt;/code&gt; fields.&lt;/p&gt;

&lt;h2&gt;
  
  
  JEP 504 Remove the Applet API
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://openjdk.org/jeps/504" rel="noopener noreferrer"&gt;JEP&lt;/a&gt; link.&lt;/p&gt;

&lt;p&gt;The nine-year saga is coming to an end. Yes, now applets are gone.&lt;/p&gt;

&lt;p&gt;Here's the whole timeline of the applet removal:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;2017 (&lt;a href="https://openjdk.org/jeps/289" rel="noopener noreferrer"&gt;JEP 289&lt;/a&gt;, JDK 9), applets are marked as &lt;code&gt;Deprecated&lt;/code&gt; because browsers no longer support them.&lt;/li&gt;
&lt;li&gt;2018 (JDK 11), Appletviewer, which enabled testing applets outside a browser, is &lt;a href="https://bugs.openjdk.org/browse/JDK-8200549" rel="noopener noreferrer"&gt;removed&lt;/a&gt;. No more applet testing in the JDK.&lt;/li&gt;
&lt;li&gt;2020 (&lt;a href="https://openjdk.org/jeps/398" rel="noopener noreferrer"&gt;JEP 398&lt;/a&gt;, JDK 17), the applet API is marked with &lt;code&gt;forRemoval=true&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;2024 (&lt;a href="https://openjdk.org/jeps/486" rel="noopener noreferrer"&gt;JEP 486&lt;/a&gt;, JDK 24), &lt;code&gt;SecurityManager&lt;/code&gt;, which handled security during applet execution, is removed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So now, in 2026, nine years after the efforts to remove the Applet API began, this whole story has come to its logical conclusion! &lt;/p&gt;

&lt;p&gt;They weren't even 33 years old... Gone too soon, never truly understood.&lt;/p&gt;

&lt;h2&gt;
  
  
  JEP 517 HTTP/3
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://openjdk.org/jeps/517" rel="noopener noreferrer"&gt;JEP&lt;/a&gt; link.&lt;/p&gt;

&lt;p&gt;Java 11 &lt;a href="https://pvs-studio.com/en/blog/posts/java/1337/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1370#IDB3E97262DA" rel="noopener noreferrer"&gt;introduced &lt;code&gt;HttpClient&lt;/code&gt;&lt;/a&gt;, which replaced the deprecated &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/net/HttpURLConnection.html" rel="noopener noreferrer"&gt;&lt;code&gt;HttpUrlConnection&lt;/code&gt;&lt;/a&gt;. It handles HTTP requests using HTTP/1.1 and HTTP/2. The HTTP/3 protocol was standardized in 2022. According to &lt;a href="https://w3techs.com/technologies/details/ce-http3" rel="noopener noreferrer"&gt;W3Techs&lt;/a&gt;, more than a third of web servers already support it. &lt;/p&gt;

&lt;p&gt;So, the time has come: this JEP adds support for HTTP/3 requests to &lt;code&gt;HttpClient&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;To make client requests use HTTP/3, the proper flag must be explicitly set when configuring &lt;code&gt;HttpClient&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;newBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                       &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Version&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HTTP_3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
                       &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alternatively, you can do the same when configuring the query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HttpRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;newBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;URI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://openjdk.org/"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                         &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Version&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HTTP_3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
                         &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, if the target server doesn't support HTTP/3, the request will be downgraded under the hood—first to HTTP/2, and then to HTTP/1.1 if necessary.&lt;/p&gt;

&lt;p&gt;The benefits of using HTTP/3 include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Faster handshakes.&lt;/li&gt;
&lt;li&gt;More reliable data transmission.&lt;/li&gt;
&lt;li&gt;Fixing the &lt;a href="https://en.wikipedia.org/wiki/Head-of-line_blocking" rel="noopener noreferrer"&gt;head-of-line blocking&lt;/a&gt; issue.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  JEP 526 Lazy Constants (Second Preview)
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://openjdk.org/jeps/526" rel="noopener noreferrer"&gt;JEP&lt;/a&gt; link.&lt;/p&gt;

&lt;p&gt;On to the preview features. This JEP is a direct follow-up to &lt;a href="https://openjdk.org/jeps/502" rel="noopener noreferrer"&gt;JEP 502: Stable Values&lt;/a&gt;. Let's briefly recap what it's about.&lt;/p&gt;

&lt;p&gt;These changes will add an API for defining lazy constants. Currently, static constants are initialized when a class is loaded, even if they won't be used until way later (or at all). This JEP will introduce an entity that combines immutability with lazily initialized values—only when accessed.&lt;/p&gt;

&lt;p&gt;The advantages include better startup performance and the ability to optimize these values just like constants.&lt;/p&gt;

&lt;p&gt;In the second preview:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The API under development has been renamed from &lt;code&gt;StableValue&lt;/code&gt; to the higher-level &lt;code&gt;LazyConstant&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Some low-level methods and factories have been removed. Only high-level factories that take values directly remain available.&lt;/li&gt;
&lt;li&gt;For optimization purposes, &lt;code&gt;null&lt;/code&gt; is no longer allowed as a computed value.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  JEP 529 Vector API (Eleventh Incubator)
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://openjdk.org/jeps/529" rel="noopener noreferrer"&gt;JEP&lt;/a&gt; link.&lt;/p&gt;

&lt;p&gt;If you need a refresher on what the Vector API is, here's a quick overview.&lt;/p&gt;

&lt;p&gt;The Vector API enables vector computation to Java at the CPU level and provides data-level parallelism. The goal is to pair raw performance with developer-friendly, high-level API.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What's vector computation?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Vector computation is a way for processors to operate on data vectors using the &lt;a href="https://en.wikipedia.org/wiki/Single_instruction,_multiple_data" rel="noopener noreferrer"&gt;SIMD (Single Instruction, Multiple Data)&lt;/a&gt; architecture, where a single machine instruction is applied in parallel to all elements of the vector.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;First, it's worth noting the irony of this JEP staying in the Incubator for the &lt;a href="https://openjdk.org/jeps/11" rel="noopener noreferrer"&gt;11th time&lt;/a&gt;. Simple math calculations reveal that the feature was first introduced in Java 16 (&lt;a href="https://openjdk.org/jeps/338" rel="noopener noreferrer"&gt;JEP 338&lt;/a&gt;). &lt;/p&gt;

&lt;p&gt;According to the authors themselves, there are no significant changes in this particular iteration. This feature is scheduled for release with &lt;a href="https://openjdk.org/projects/valhalla/" rel="noopener noreferrer"&gt;Project Valhalla&lt;/a&gt;, and once that lands, Vector API will be available in Preview. No firm release date yet, but hopefully, it'll be out as soon as possible. After all, both the Vector API and &lt;a href="https://openjdk.org/jeps/401" rel="noopener noreferrer"&gt;Value Classes&lt;/a&gt; sound like cool and niche features.&lt;/p&gt;

&lt;h2&gt;
  
  
  JEP 530 Primitive Types in Patterns, instanceof, and switch (Fourth Preview)
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://openjdk.org/jeps/530" rel="noopener noreferrer"&gt;JEP&lt;/a&gt; link.&lt;/p&gt;

&lt;p&gt;That bring us to the final JEP on today's list; the 4th preview of a feature that enables using primitives in pattern-matching constructs with the &lt;code&gt;instanceof&lt;/code&gt; and &lt;code&gt;switch&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It may look something like this. The &lt;code&gt;switch&lt;/code&gt; statement before:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getStatus&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"okay"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"warning"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"unknown status: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getStatus&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The after:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getStatus&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"okay"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"warning"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"unknown status: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This fourth preview doesn't introduce any new APIs or features, but it does clarify and expand the way the language behaves with two new things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://openjdk.org/jeps/530#Safety-of-conversions" rel="noopener noreferrer"&gt;&lt;strong&gt;Safety of conversion&lt;/strong&gt;&lt;/a&gt; is a formalization that describes possible primitive type conversions for pattern matching (specifying which are safe, which may result in data loss, and which are uncompilable).&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://openjdk.org/jeps/530#Dominance" rel="noopener noreferrer"&gt;&lt;strong&gt;Dominance&lt;/strong&gt;&lt;/a&gt; is a compile-time check ensuring that one &lt;code&gt;case&lt;/code&gt; branch doesn't dominate another. If it does, Java 26 will now throw a compilation error. As a result, some Java 25 code won't compile in Java 26.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here are some examples of uncompilable constructs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;...;&lt;/span&gt;
&lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="kt"&gt;short&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;      &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;   &lt;span class="c1"&gt;// error: dominated since 42 can be&lt;/span&gt;
                         &lt;span class="c1"&gt;// converted unconditionally exactly to short&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;...;&lt;/span&gt;
&lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;      &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;  &lt;span class="c1"&gt;// unconditional pattern&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;  &lt;span class="c1"&gt;// error: dominated&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Java 26 didn't ship a ton of new features or APIs on its own. Still, this update brought quite a few changes that enhanced what's already there. The &lt;code&gt;final&lt;/code&gt; modifier, &lt;code&gt;Lazy Constants&lt;/code&gt;, and everything else are part of the ongoing trend toward optimizing Java program execution. &lt;/p&gt;

&lt;p&gt;It's great that Java is never standing still. The optimizations, the ongoing API work, and everything in between are a clear sign that Java is more alive than ever and still going strong. &lt;/p&gt;

&lt;p&gt;You can find the original descriptions of all the changes &lt;a href="https://openjdk.org/projects/jdk/26/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. If you'd like to read our previous reviews of new Java versions, check out the list below:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/blog/posts/java/1284/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1370" rel="noopener noreferrer"&gt;What's new in Java 25&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/blog/posts/java/1233/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1370" rel="noopener noreferrer"&gt;What's new in Java 24&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>jdk</category>
      <category>oracle</category>
      <category>news</category>
    </item>
    <item>
      <title>Silent foe or quiet ally: Brief guide to alignment in C++. Part 3</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Thu, 30 Apr 2026 11:34:09 +0000</pubDate>
      <link>https://forem.com/pvsdev/silent-foe-or-quiet-ally-brief-guide-to-alignment-in-c-part-3-3f9j</link>
      <guid>https://forem.com/pvsdev/silent-foe-or-quiet-ally-brief-guide-to-alignment-in-c-part-3-3f9j</guid>
      <description>&lt;p&gt;We've already covered basic field alignment and explored how inheritance layers data atop one another. By now you might think we have uncovered every trap. But not so fast! This topic has a truly dark side that few discuss. One short word—virtual—completely rewrites a class "geometry," introducing alignment corrections we can't ignore. Let's find out what really happens under the hood when alignment meets virtuality.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2For3dcsrqo0j13zavrdpt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2For3dcsrqo0j13zavrdpt.png" alt="1369_Alignment3/image1.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;We continue our deep dive into memory mechanics. If you are just joining us, I recommend reviewing the foundations first. The &lt;a href="https://pvs-studio.com/en/blog/posts/cpp/1339/" rel="noopener noreferrer"&gt;first part&lt;/a&gt; covered the basics and the magic of simple data alignment, while the &lt;a href="https://pvs-studio.com/en/blog/posts/cpp/1340/" rel="noopener noreferrer"&gt;second part&lt;/a&gt; focused on how ordinary inheritance affects memory layout.&lt;/p&gt;

&lt;p&gt;So far, we've treated an object as a static, rigidly determined data structure. Every field address was known at compile time, and inheritance simply layered parent and child attributes. Alas, object-oriented programming is impossible without dynamic polymorphism, which is implemented in C++ via the RTTI mechanism and virtual functions.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is virtuality?
&lt;/h2&gt;

&lt;p&gt;Let me start from an off-topic question. How does the compiler know which piece of machine code to execute at a specific line in your program? Answering this question will help us understand what virtuality really means.&lt;/p&gt;

&lt;p&gt;Imagine we write &lt;code&gt;object.print()&lt;/code&gt;. For the processor, it's not an abstract action but a command to jump to a certain address in memory with some function instructions. But where do we take that address from?&lt;/p&gt;

&lt;p&gt;During compilation, each code line becomes one or more machine instructions, each receives a unique sequential address in memory. The same applies to functions. A compiler translates them into machine code and assigns the next available address. Stitching a function call in code to its actual memory address is called &lt;strong&gt;binding&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Depending on when the call address is bound to the function address, there are two scenarios.&lt;/p&gt;

&lt;p&gt;1. &lt;strong&gt;Static/early binding&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;By default, static (early) binding is used. A compiler rigidly "hardwires" a specific function address at the call place in code during compilation. This decision relies solely on the pointer or reference type, not the actual object in memory. For instance, when a compiler sees a &lt;code&gt;Base*&lt;/code&gt; pointer, it chooses the method address from the base class. It's fast and requires no additional evaluations. So, the jump goes to an already known address. It's also efficient, but it makes the program inflexible at runtime.&lt;/p&gt;

&lt;p&gt;2. &lt;a href="https://en.wikipedia.org/wiki/Late_binding" rel="noopener noreferrer"&gt;&lt;strong&gt;Dynamic/late binding&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Unlike static binding, dynamic (late) binding postpones function selection until the program runs. In this case, a compiler can't insert a specific function address into the code in advance. Instead, it generates a special instruction: "At the moment of call, look inside the object, find the current address of the needed function, and only then jump." This provides tremendous flexibility: the program makes decisions on the fly based on which object is currently in front of it (a derived class or a base class), rather than on the pointer type we are using.&lt;/p&gt;

&lt;p&gt;Now that we've covered the mechanics of binding, we can answer the question of what virtuality actually is. Virtuality is a mechanism that implements dynamic polymorphism based on late binding. By marking a method with the &lt;code&gt;virtual&lt;/code&gt; keyword, we shift it from static binding to late binding. From this point on, the address of the function's entry point is no longer a compile-time constant but a variable whose value derives from the context of a specific object at runtime.&lt;/p&gt;

&lt;p&gt;The C++ standard doesn't specify how virtuality must be implemented, but de facto it follows the rules of specific ABIs (Itanium ABI, MSVC ABI). The key components here are the &lt;code&gt;vtable&lt;/code&gt; (Virtual Method Table) and &lt;code&gt;vptr&lt;/code&gt; (Virtual Pointer).&lt;/p&gt;

&lt;h2&gt;
  
  
  Virtual functions
&lt;/h2&gt;

&lt;p&gt;We have unpacked the concept of virtuality, but in practice the main tool for its implementation is the virtual function. Let's see how it works.&lt;/p&gt;

&lt;p&gt;Here's a simple class hierarchy where we attempt to override a parent method in a derived class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string_view&lt;/span&gt; &lt;span class="n"&gt;NameClass&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Base"&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;  
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string_view&lt;/span&gt; &lt;span class="n"&gt;NameClass&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Derived"&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;
  Full code fragment
  &lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;format&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;string_view&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string_view&lt;/span&gt; &lt;span class="n"&gt;NameClass&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Base"&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;  
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string_view&lt;/span&gt; &lt;span class="n"&gt;NameClass&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Derived"&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;

&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Derived&lt;/span&gt; &lt;span class="n"&gt;derived&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
  &lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;derived&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"=== Name class ===&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Base has static type "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NameClass&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;/p&gt;

&lt;p&gt;
  Program output
  &lt;br&gt;
&lt;a href="https://godbolt.org/z/77eT5Ters" rel="noopener noreferrer"&gt;Compiler Explorer&lt;/a&gt;&lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt;
&lt;span class="n"&gt;Base&lt;/span&gt; &lt;span class="n"&gt;has&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;/p&gt;

&lt;p&gt;The result may seem strange. We created a &lt;code&gt;Derived&lt;/code&gt; object, but the program insists it's &lt;code&gt;Base&lt;/code&gt;. Early bonding is to blame here. The compiler sees the &lt;code&gt;Base&amp;amp;&lt;/code&gt; reference and determines the method call at build time. From its perspective, this is a safe and fast optimization—it doesn't have to check what type of object the reference points to while the program is running.&lt;/p&gt;

&lt;p&gt;Let's move the decision from compile time to runtime by adding just one word—&lt;code&gt;virtual&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string_view&lt;/span&gt; &lt;span class="n"&gt;NameClass&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Base"&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;  
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string_view&lt;/span&gt; &lt;span class="n"&gt;NameClass&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Derived"&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;
  Full code fragment
  &lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;format&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;string_view&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string_view&lt;/span&gt; &lt;span class="n"&gt;NameClass&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Base"&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;  
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string_view&lt;/span&gt; &lt;span class="n"&gt;NameClass&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Derived"&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;

&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Derived&lt;/span&gt; &lt;span class="n"&gt;derived&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
  &lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;derived&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"=== Name class ===&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Base has static type "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NameClass&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;/p&gt;

&lt;p&gt;
  Program output
  &lt;br&gt;
&lt;a href="https://godbolt.org/z/K6M6MfvEz" rel="noopener noreferrer"&gt;Compiler Explorer&lt;/a&gt;&lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;
&lt;span class="n"&gt;Base&lt;/span&gt; &lt;span class="n"&gt;has&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Derived&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;/p&gt;

&lt;p&gt;Seems like it worked out. Despite the reference, the program now sees the object real type in memory. Dynamic binding kicks in: the function address selection occurs at &lt;a href="https://en.wikipedia.org/wiki/Runtime" rel="noopener noreferrer"&gt;runtime&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now we can move on to the definition. A virtual function is a class method that is called not based on a reference or pointer type, but on the actual type of the object in memory. The &lt;code&gt;virtual&lt;/code&gt; keyword instructs the compiler to replace a direct function call with a &lt;a href="https://en.wikipedia.org/wiki/Dynamic_dispatch" rel="noopener noreferrer"&gt;dynamic dispatch&lt;/a&gt;. This way, a derived class can override the implementation of a base class while maintaining the same structure.&lt;/p&gt;

&lt;p&gt;We'll focus on the pros and cons of virtual functions later, but first note: the C++ standard describes the expected behavior of virtual functions but leaves implementation details to compiler developers. But the vast majority of modern compilers (GCC, Clang, MSVC) use a mechanism that has become the default standard: virtual function tables.&lt;/p&gt;

&lt;h2&gt;
  
  
  Virtual function table (vtable)
&lt;/h2&gt;

&lt;p&gt;A virtual table (&lt;a href="https://en.wikipedia.org/wiki/Virtual_method_table" rel="noopener noreferrer"&gt;vtable, virtual method table, dispatch table&lt;/a&gt;) is a static array of pointers that the compiler creates for each class that uses virtual functions (or inherits from such classes).&lt;/p&gt;

&lt;p&gt;Let's start with a piece of theory. How does a &lt;code&gt;vtable&lt;/code&gt; work?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The compiler creates the table once per class at compile time, not per object.&lt;/li&gt;
&lt;li&gt;Each table entry points to an address of the most derived function available to that class. If a derived class overrides a function, its table stores its own version's address; if not—it stores the base class version's address.&lt;/li&gt;
&lt;li&gt;Each class in the inheritance hierarchy receives its own unique &lt;code&gt;vtable&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The table itself is only a static structure in memory. To ensure that a specific object knows which table to use, the compiler implicitly adds a hidden field—&lt;code&gt;vptr&lt;/code&gt;—to every instance of the class. The constructor initializes it and links the object to its &lt;code&gt;vtable&lt;/code&gt;. More on this later.&lt;/li&gt;
&lt;li&gt;The compiler strictly determines the function order in the table at compile time. For example, if &lt;code&gt;funcA()&lt;/code&gt; is listed first in the base class, it occupies the first index in all derived class tables. As a result, the program finds the desired address in constant time O(1) simply by adding the offset to the table address.&lt;/li&gt;
&lt;li&gt;Besides function addresses, the &lt;code&gt;vtable&lt;/code&gt; often contains a pointer to a structure with type information (Run-Time Type Information, &lt;a href="https://en.wikipedia.org/wiki/Run-time_type_information" rel="noopener noreferrer"&gt;RTTI&lt;/a&gt;). This ensures correct functioning of operators that check the actual object type directly during program execution.&lt;/li&gt;
&lt;li&gt;If a polymorphic class is designed correctly, one of the entries in its &lt;code&gt;vtable&lt;/code&gt; is always reserved for the destructor. This guarantees that deleting an object via a base class pointer calls the destructor chain of all derived classes to prevent memory leaks.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The chart below illustrates the process:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxfxisri71s9oshpezd8z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxfxisri71s9oshpezd8z.png" alt="1369_Alignment3/image2.png" width="800" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What have we got here? A memory-level architecture of dynamic polymorphism. The linking element is the &lt;code&gt;vptr&lt;/code&gt;, which is a hidden 8-byte pointer at the beginning of the class that redirects calls to the &lt;code&gt;vtable&lt;/code&gt;. In this table, the negative index stores type metadata (RTTI), while the zero index stores the address of the virtual destructor. The remaining entries contain physical addresses of the functions. This fixed order is crucial, as calling any method boils down to two operations: reading from and writing to memory.&lt;/p&gt;

&lt;p&gt;When the code contains a call to a virtual function via a pointer or a reference to the base class, the following steps execute:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The program accesses a class instance and, through its hidden pointer, finds the corresponding virtual table for its actual type.&lt;/li&gt;
&lt;li&gt;The program selects the required entry in the table, since the compiler already knows the function index.&lt;/li&gt;
&lt;li&gt;The program extracts the function address from that entry.&lt;/li&gt;
&lt;li&gt;The program performs an indirect call to the function at the found address.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Theory always looks bright and shiny, but now let's see how it works in practice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;func1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;func2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;func1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Derived1&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;func2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's a common scenario: we've designed a base interface called &lt;code&gt;Base&lt;/code&gt; and created its subclasses. Each child class overrides some virtual functions. Logically everything is simple and clear, but let's look under the hood.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: all examples use the Clang compiler.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* vtable has 3 entries: {
       [0] = ~Base((null)), 
       [2] = func1((null)), 
       [3] = func2((null)), 
    } */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first glance it seems strange that the first index is skipped, but it's correct. The issue here is the destructor, which can be called in two different contexts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a complete object destruction—deleting an object via &lt;code&gt;delete&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;a deleting destruction—deleting an object via a base class pointer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The compiler must distinguish these two situations: it creates two entry points in the virtual table. That is why there is no first index—the destructor occupies it. Such behavior is the result of the Itanium ABI. Ordinary virtual functions follow two slots for a destructor.&lt;/p&gt;

&lt;p&gt;If we add the &lt;code&gt;-Xclang -fdump-record-layouts&lt;/code&gt; flag in Compiler Explorer, we get the following table output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt; &lt;span class="n"&gt;vtable&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quad&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quad&lt;/span&gt;   &lt;span class="n"&gt;typeinfo&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Derived&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quad&lt;/span&gt;   &lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;::~&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt; &lt;span class="n"&gt;destructor&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quad&lt;/span&gt;   &lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;::~&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;deleting&lt;/span&gt; &lt;span class="n"&gt;destructor&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quad&lt;/span&gt;   &lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;func1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quad&lt;/span&gt;   &lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;func2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the table we see that the destructor was created in two contexts.&lt;/p&gt;

&lt;p&gt;
  Full code fragment
  &lt;br&gt;
&lt;a href="https://godbolt.org/z/crYWK596M" rel="noopener noreferrer"&gt;Compiler Explorer&lt;/a&gt;&lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt; 
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;func1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;func2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;func1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Derived1&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;func2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="n"&gt;Base&lt;/span&gt; &lt;span class="n"&gt;bs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;Derived&lt;/span&gt; &lt;span class="n"&gt;dr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;Derived1&lt;/span&gt; &lt;span class="n"&gt;dr1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;/p&gt;

&lt;p&gt;We've now figured out how the compiler constructs the table of functions and sets the indices in a static array. A virtual table is simply a passive data structure that exists as a single instance for the entire class. It's just stored in memory. For polymorphism to work, we need a virtual pointer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Virtual pointer (vptr)
&lt;/h2&gt;

&lt;p&gt;The vptr (&lt;a href="https://en.wikipedia.org/wiki/Virtual_method_table" rel="noopener noreferrer"&gt;virtual methods table pointer&lt;/a&gt;) is a hidden data member (a pointer) that the compiler automatically adds to any base class containing at least one virtual function. It points to the static table of function addresses (vtable) corresponding to the object specific type at runtime.&lt;/p&gt;

&lt;h3&gt;
  
  
  How the pointer works
&lt;/h3&gt;

&lt;p&gt;Let's delve a bit into the mechanics. The vptr's operation forms the foundation of dynamic polymorphism in object-oriented languages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="n"&gt;virtualTable&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;vptr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;func1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;func2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;func1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Derived1&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;func2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's take the same code and add the virtual pointer at the beginning. It follows three fundamental stages.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;preparing infrastructure at compile time;&lt;/li&gt;
&lt;li&gt;dynamic initialization during object construction;&lt;/li&gt;
&lt;li&gt;dispatching calls in real time.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can see our code represented in the following chart:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F44c13zllkiaif5ljpoa3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F44c13zllkiaif5ljpoa3.png" alt="1369_Alignment3/image3.png" width="800" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When compiling code with virtual functions, the compiler adds a hidden &lt;code&gt;vptr&lt;/code&gt; pointer to each object, referencing the virtual function table. For the &lt;code&gt;Base&lt;/code&gt; class, it creates a &lt;code&gt;vtable&lt;/code&gt; with the addresses of its virtual methods. In derived classes (&lt;code&gt;Derived&lt;/code&gt;, &lt;code&gt;Derived1&lt;/code&gt;), the compiler replaces the addresses of overridden methods in the table while saving fixed indices for each method. This completes the first stage.&lt;/p&gt;

&lt;p&gt;Now we create a class instance via calling:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;bs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Derived&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are launching a layer-by-layer initialization process that transforms memory into a polymorphic object. First, a block of memory is allocated to store the object data and &lt;code&gt;vptr&lt;/code&gt;. The parent class constructor runs first and writes the address of its table into the pointer.&lt;/p&gt;

&lt;p&gt;Then the control passes to the &lt;code&gt;Derived&lt;/code&gt; constructor. It performs a key operation—it overwrites the pointer value, substituting the address of its own table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;vtable&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quad&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quad&lt;/span&gt;   &lt;span class="n"&gt;typeinfo&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Derived&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quad&lt;/span&gt;   &lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;::~&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt; &lt;span class="n"&gt;destructor&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quad&lt;/span&gt;   &lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;::~&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;deleting&lt;/span&gt; &lt;span class="n"&gt;destructor&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quad&lt;/span&gt;   &lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;func1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quad&lt;/span&gt;   &lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;func2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By the time all constructors are done, the object becomes stable. Its internal pointer is now firmly linked to the table of the lowest class in the hierarchy. This guarantees that any polymorphic call uses the method version corresponding to an object real type, not the pointer type. We can call this process dynamic initialization during object construction.&lt;/p&gt;

&lt;p&gt;When &lt;code&gt;bs-&amp;gt;func1()&lt;/code&gt; is executed, a dynamic call dispatch mechanism (based on the principle of late binding) triggers. The compiler generates the code that ignores the static type of the &lt;code&gt;Base*&lt;/code&gt; pointer and instead extracts the current pointer value from the object memory. It contains the address of the actual virtual table for the real dynamic type. The &lt;code&gt;vtable&lt;/code&gt; is then indirectly accessed via the &lt;code&gt;vptr&lt;/code&gt;. Using a fixed offset in that table, the program gets the address of the required method implementation. The processor jumps to that address, ensuring the call of the overridden method from &lt;code&gt;Derived&lt;/code&gt; rather than the base implementation.&lt;/p&gt;

&lt;p&gt;
  Full code fragment
  &lt;br&gt;
&lt;a href="https://godbolt.org/z/bz1Peooza" rel="noopener noreferrer"&gt;Compiler Explorer&lt;/a&gt;&lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;func1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;func2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;func1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Derived1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;func2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;bs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;func1&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;/p&gt;

&lt;p&gt;Now that we understand how the &lt;code&gt;vptr&lt;/code&gt; enables polymorphism, we should look at its physical impact on the object. Since the pointer is a full-fledged field within the structure, its presence inevitably adjusts memory topology. Let's break down how introducing this pointer triggers alignment mechanisms and affects the structure final size in bytes.&lt;/p&gt;

&lt;h3&gt;
  
  
  The alignment and vptr
&lt;/h3&gt;

&lt;p&gt;In modern 64-bit systems, the virtual pointer occupies 8 bytes. According to most ABI specifications, data must align to an address that is a multiple of its own size. So, the virtual pointer requires 8-byte alignment.&lt;/p&gt;

&lt;p&gt;How does this affect offsets?  Since the pointer field takes the first 8 bytes, we can't arbitrarily place any following field—the compiler must adhere to the alignment rules for each data type within the structure.&lt;/p&gt;

&lt;p&gt;Let's recall how field placement works. If the &lt;code&gt;vptr&lt;/code&gt; is followed by a type with a lower alignment requirement, such as &lt;code&gt;char&lt;/code&gt;, it will occupy the next byte. However, if it is followed by a type that requires 4 or 8 bytes, the compiler will insert padding to align the address of the next field. Let's look at the example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Example&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;  
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What is its alignment? Mathematically the size would be 9 bytes, but there's a catch. The answer is 16 bytes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="o"&gt;***&lt;/span&gt; &lt;span class="n"&gt;Dumping&lt;/span&gt; &lt;span class="n"&gt;AST&lt;/span&gt; &lt;span class="n"&gt;Record&lt;/span&gt; &lt;span class="n"&gt;Layout&lt;/span&gt;
         &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Example&lt;/span&gt;
         &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Example&lt;/span&gt; &lt;span class="n"&gt;vtable&lt;/span&gt; &lt;span class="n"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;
           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;align&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;nvsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nvalign&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The final size arithmetic is straightforward: 8 bytes for the pointer, 1 byte for data, and 7 bytes for final alignment. But to figure out how this object will behave within the inheritance hierarchy, we need to interpret the specification generated by the compiler. What do the terms &lt;code&gt;dsize&lt;/code&gt;, &lt;code&gt;nvsize&lt;/code&gt;, and &lt;code&gt;nvalign&lt;/code&gt; mean? Let's break them down.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;sizeof&lt;/code&gt; is the final object size in bytes.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dsize&lt;/code&gt; is the actual memory volume used by useful data. We put it together using 8 bytes of &lt;code&gt;vptr&lt;/code&gt; and 1 byte of &lt;code&gt;char&lt;/code&gt;. Basically, this is the raw size of the object state before the final alignment rules are applied.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;align&lt;/code&gt; is the address alignment requirement for the object in memory. Since the most restrictive type in the class is an 8-byte pointer, the entire object is assigned an alignment attribute of 8.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;nvsize&lt;/code&gt; is the size of the "non-virtual" part of the class. In the context of single inheritance, this refers to the amount of memory occupied by a class when it serves as the base class for another. In our example, it matches &lt;code&gt;dsize&lt;/code&gt; because the hierarchy is simple.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;nvalign&lt;/code&gt; is the alignment that a derived class must maintain when placing its own fields.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Armed with this solid foundation, we can now dive into a really dark topic—inheritance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inheritance and virtuality
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The diamond problem
&lt;/h3&gt;

&lt;p&gt;Look at the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Entity&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Movable&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;velocity&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;move&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Renderable&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;textureId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;draw&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Player&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Movable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Renderable&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
   &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first glance, this appears logical and well-structured. Let's try using this class in code and see the result.&lt;/p&gt;

&lt;p&gt;Creating a &lt;code&gt;Player&lt;/code&gt; object and looking at its memory layout reveals something strange:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;Player&lt;/span&gt; &lt;span class="n"&gt;hero&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;***&lt;/span&gt; &lt;span class="n"&gt;Dumping&lt;/span&gt; &lt;span class="n"&gt;AST&lt;/span&gt; &lt;span class="n"&gt;Record&lt;/span&gt; &lt;span class="n"&gt;Layout&lt;/span&gt;
         &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Player&lt;/span&gt;
         &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Movable&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;primary&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Entity&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;primary&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;vtable&lt;/span&gt; &lt;span class="n"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;
        &lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;velocity&lt;/span&gt;
        &lt;span class="mi"&gt;16&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Renderable&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="mi"&gt;16&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Entity&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;primary&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="mi"&gt;16&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;vtable&lt;/span&gt; &lt;span class="n"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;
        &lt;span class="mi"&gt;28&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;textureId&lt;/span&gt;
        &lt;span class="mi"&gt;32&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;align&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;nvsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nvalign&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of carefully combining properties from all ancestors, the compiler literally "glues" two complete structures: &lt;code&gt;Renderable&lt;/code&gt; and &lt;code&gt;Movable&lt;/code&gt;. The diagram shows the class relationships:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fspk6af5e6p9d8c9ndoky.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fspk6af5e6p9d8c9ndoky.png" alt="1369_Alignment3/image4.png" width="800" height="627"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The problem is that both parent classes already contain a full copy of the &lt;code&gt;Entity&lt;/code&gt; base class. As a result, there are two independent &lt;code&gt;Entity&lt;/code&gt; instances within a single &lt;code&gt;Player&lt;/code&gt; object. Each has its own &lt;code&gt;vptr&lt;/code&gt; and its own &lt;code&gt;id&lt;/code&gt; field. From the perspective of binary structure, the object is redundant: it doesn't simply inherit functionality, but physically duplicates the state of the base class in different segments of its memory.&lt;/p&gt;

&lt;p&gt;This structural issue pops up at the worst possible moment—when we try to simply access a player's ID:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;hero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0wkc4s3jf8zorzyshn95.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0wkc4s3jf8zorzyshn95.png" alt="1369_Alignment3/image5.png" width="800" height="213"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The compiler hits a dead end. It sees that the &lt;code&gt;hero&lt;/code&gt; object has two paths to the &lt;code&gt;id&lt;/code&gt; field:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;via the movement branch (&lt;code&gt;Movable&lt;/code&gt;);&lt;/li&gt;
&lt;li&gt;via the rendering branch (&lt;code&gt;Renderable&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In memory these fields exist separately from each other: the program can't guess which identifier we intend to modify. We end up with an object with an inconsistent internal state: one memory area allocated for &lt;code&gt;Entity&lt;/code&gt; (via &lt;code&gt;Movable&lt;/code&gt;) may store the value &lt;code&gt;id = 1&lt;/code&gt;, while the second area (via &lt;code&gt;Renderable&lt;/code&gt;) remains uninitialized or contain a different value. Since these are two physically distinct address-space locations, writing to one has no effect on the other. This situation is called the &lt;a href="https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem" rel="noopener noreferrer"&gt;&lt;strong&gt;diamond problem&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;
  Full code fragment
  &lt;br&gt;
&lt;a href="https://godbolt.org/z/3MY8d8j77" rel="noopener noreferrer"&gt;Compiler Explorer&lt;/a&gt;&lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Entity&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Movable&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;velocity&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;move&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Renderable&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;textureId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;draw&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Player&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Movable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Renderable&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Player&lt;/span&gt; &lt;span class="n"&gt;hero&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;hero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;/p&gt;

&lt;p&gt;To eliminate this redundancy and restore consistency, we should use virtual inheritance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Entity&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Entity update, ID "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Movable&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;velocity&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;move&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Moving with velocity "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;velocity&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Renderable&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;textureId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;draw&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Drawing texture "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;textureId&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Player&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Movable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Renderable&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; 
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Player "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;" updating ... "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In that case, the compiler changes the algorithm to construct the object. Instead of statically embedding &lt;code&gt;Entity&lt;/code&gt; data into each branch, it allocates a single shared memory area for the base class. Now the final &lt;code&gt;Player&lt;/code&gt; object will contain only one instance of &lt;code&gt;id&lt;/code&gt; and one set of virtual methods regardless of the number of intermediate classes. This area is accessed via additional offset pointers, ensuring the object logical and physical unity.&lt;/p&gt;

&lt;p&gt;
  Full code fragment
  &lt;br&gt;
&lt;a href="https://godbolt.org/z/jPofMnfz3" rel="noopener noreferrer"&gt;Compiler Explorer&lt;/a&gt;&lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;cstring&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Entity&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Entity update, ID "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Movable&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;velocity&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;move&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Moving with velocity "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;velocity&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Renderable&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;textureId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;draw&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Drawing texture "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;textureId&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Player&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Movable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Renderable&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; 
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Player "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;" updating ... "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Player&lt;/span&gt; &lt;span class="n"&gt;hero&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;hero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;hero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;velocity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;6.5&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;hero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;textureId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;strcpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Tom"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;hero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;hero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;move&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;hero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;draw&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;/p&gt;

&lt;p&gt;
  Program output
  &lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;Player&lt;/span&gt; &lt;span class="n"&gt;Tom&lt;/span&gt; &lt;span class="n"&gt;updating&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; 
&lt;span class="n"&gt;Moving&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="n"&gt;velocity&lt;/span&gt; &lt;span class="mf"&gt;6.5&lt;/span&gt;
&lt;span class="n"&gt;Drawing&lt;/span&gt; &lt;span class="n"&gt;texture&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;/p&gt;

&lt;h3&gt;
  
  
  Virtual inheritance mechanisms: vbptr, vbtable, VTT
&lt;/h3&gt;

&lt;p&gt;Virtual inheritance disrupts the usual linear memory layout. The compiler once knew the exact address of the id field from the start of the object, but now that certainty is lost. The virtual base becomes a dynamic component: one day it's a part of &lt;code&gt;Player&lt;/code&gt;, another day —a part of &lt;code&gt;Movable&lt;/code&gt;. Its exact location in memory depends on a specific hierarchy in which the final object was built.&lt;/p&gt;

&lt;p&gt;To avoid guessing addresses, the compiler introduces an indirect addressing mechanism via the &lt;code&gt;vbptr&lt;/code&gt; (virtual base pointer) and &lt;code&gt;vbtable&lt;/code&gt; (virtual base table). Each intermediate class that virtually inherits a base receives a hidden pointer—the &lt;code&gt;vbptr&lt;/code&gt;. It serves as an entry point to a static offset table (vbtable) that the compiler generates for a specific type whose object contains this &lt;code&gt;vbptr&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The table stores integer values that define the exact distance from the current &lt;code&gt;vbptr&lt;/code&gt; position to the start of the parent's virtual base. Therefore, any access to a field transforms into the following algorithm:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;read the address from the &lt;code&gt;vbptr&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;extract the needed offset from the &lt;code&gt;vbtable&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;add the current object address and the retrieved offset to get the final physical data address.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now that we understand how the process goes, we can provide definitions.&lt;/p&gt;

&lt;p&gt;vbptr (virtual base pointer) is a hidden system pointer that the compiler inserts in the layout of a derived class. It acts as a dynamic reference to an offset table, enabling an object to determine at runtime, where its virtual ancestor locates in the current memory configuration.&lt;/p&gt;

&lt;p&gt;vbtable (virtual base table) is a static data structure that the compiler generates for each type that uses virtual inheritance. This structure is an array of integer values that specify the exact distance in bytes from the &lt;code&gt;vbptr&lt;/code&gt; to the start of each virtual base subobject.&lt;/p&gt;

&lt;p&gt;Regular polymorphism and virtual inheritance are often confused, here is a table to show the difference:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpmea1zhn85cpjrir5zs3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpmea1zhn85cpjrir5zs3.png" alt="1369_Alignment3/image6.png" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After reviewing the comparison table and understanding how individual pointers work, a question arises: how does this complex machinery spring into action? If the &lt;code&gt;vtable&lt;/code&gt; and &lt;code&gt;vbtable&lt;/code&gt; are static tables, then when creating an object, we need a mechanism that will correctly set all the pointers to their proper locations. In complex hierarchies with virtual inheritance, the VTT (Virtual Method Table Hierarchy Table) plays this role within the Itanium ABI.&lt;/p&gt;

&lt;p&gt;A &lt;a href="https://nimrod.blog/posts/cpp-virtual-table-tables/" rel="noopener noreferrer"&gt;VTT&lt;/a&gt; is a data structure that can be informally described as a "table of tables."While a regular virtual table stores function addresses, a VTT stores the addresses of the virtual tables that are needed for a specific inheritance branch. The key technical task of the VTT is to ensure correct object behavior during that borderline moment when the base class constructor has already launched but the derived class constructor hasn't finished yet. Without this mechanism, calling a virtual function or accessing virtual base data from a constructor could result in a crash. It's because the object isn't fully built yet and its pointers may reference incorrect or empty areas.&lt;/p&gt;

&lt;p&gt;The VTT operation follows this algorithm.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;When the most derived class constructor is called, the compiler secretly passes it the address of the corresponding VTT as an argument.&lt;/li&gt;
&lt;li&gt;The compiler reads the addresses of the initial and secondary virtual tables from the VTT and writes them to the &lt;code&gt;vptr&lt;/code&gt; and &lt;code&gt;vbptr&lt;/code&gt; of the current object.&lt;/li&gt;
&lt;li&gt;When constructors of base classes are called, they receive not the entire VTT but only a pointer to its specific fragment for the relevant branch.&lt;/li&gt;
&lt;li&gt;The base class uses the received fragment to temporarily adjust the object pointers ensuring that, for the duration of its constructor, the object behaves as an instance of that specific base class.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now that we've figured out who's responsible for what, we can move on to alignment in the virtual environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  The pitfalls of virtual inheritance
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Pointer casting
&lt;/h4&gt;

&lt;p&gt;Let's look at the challenges we might face with virtual inheritance. The first issue surfaces when we cast a pointer from a derived class to its base types. We are used to thinking of a pointer to an object as a static label that points to the start of a memory block. However, multiple and virtual inheritance introduce their own complications.&lt;/p&gt;

&lt;p&gt;Look at this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Parent1&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;Parent1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Parent2&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;num2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;Parent2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; 
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Parent1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Parent2&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we have a classic scenario of multiple inheritance: two parents and one child. Let's output their addresses.&lt;/p&gt;

&lt;p&gt;
  Full code fragment
  &lt;br&gt;
&lt;a href="https://godbolt.org/z/eTTPnYPx5" rel="noopener noreferrer"&gt;Compiler Explorer&lt;/a&gt;&lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt;  &lt;span class="cpf"&gt;&amp;lt;cstring&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Parent1&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;Parent1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Parent2&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;num2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;Parent2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; 
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Parent1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Parent2&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;Parent1&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;p1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;Parent2&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;p2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Derived address: "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Parent1 address: "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;p1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Parent2 address: "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;p2&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;/p&gt;

&lt;p&gt;
  Program output
  &lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;Derived&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;0x55b3bf4b92b0&lt;/span&gt;
&lt;span class="n"&gt;Parent1&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;0x55b3bf4b92b0&lt;/span&gt;
&lt;span class="n"&gt;Parent2&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;0x55b3bf4b92c0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;/p&gt;

&lt;p&gt;If we run this code, we'll see something strange: the addresses of &lt;code&gt;Derived&lt;/code&gt; and &lt;code&gt;Parent2&lt;/code&gt; differ. Here we see a fundamental peculiarity: the same object can have different addresses depending on the type of pointer used to access it.&lt;/p&gt;

&lt;p&gt;We expect that a pointer to an object always points to the start of the corresponding subobject in memory. Since &lt;code&gt;Derived&lt;/code&gt; contains &lt;code&gt;Parent1&lt;/code&gt; and &lt;code&gt;Parent2&lt;/code&gt;, they can't share the same location. The compiler places them one after another.&lt;/p&gt;

&lt;p&gt;Thus, when we wrote &lt;code&gt;Parent2* p2 = d;&lt;/code&gt; more than just bit copying occurred—the compiler performed a pointer adjustment. It took the address of the &lt;code&gt;Derived&lt;/code&gt; start and added an offset so that &lt;code&gt;p2&lt;/code&gt; would point only to the beginning of the data related to &lt;code&gt;Parent2&lt;/code&gt;. In ordinary multiple inheritance this offset is static, but when virtuality enters, the situation becomes dynamic.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The order of base classes in memory can change depending on the hierarchy.&lt;/li&gt;
&lt;li&gt;The compiler can no longer add +16 bytes to the code.&lt;/li&gt;
&lt;li&gt;The compiler generates code that accesses the &lt;code&gt;vbtable&lt;/code&gt;, gets the current offset for the object type, and adds it to the address.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What's going on with the alignment here? It also makes its own changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="o"&gt;***&lt;/span&gt; &lt;span class="n"&gt;Dumping&lt;/span&gt; &lt;span class="n"&gt;AST&lt;/span&gt; &lt;span class="n"&gt;Record&lt;/span&gt; &lt;span class="n"&gt;Layout&lt;/span&gt;
         &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt;
         &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Parent1&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;primary&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Parent1&lt;/span&gt; &lt;span class="n"&gt;vtable&lt;/span&gt; &lt;span class="n"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;
        &lt;span class="mi"&gt;16&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Parent2&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="mi"&gt;16&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Parent2&lt;/span&gt; &lt;span class="n"&gt;vtable&lt;/span&gt; &lt;span class="n"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;num2&lt;/span&gt;
        &lt;span class="mi"&gt;28&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;
           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;align&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;nvsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nvalign&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Parent1&lt;/code&gt; is located at the very beginning (at offset 0), but instead of the expected 4 bytes for &lt;code&gt;int num&lt;/code&gt;, it takes up 16. The reason is the virtual destructor that forces the compiler to insert an 8-byte &lt;code&gt;vptr&lt;/code&gt; and add 4 bytes of padding after the &lt;code&gt;num&lt;/code&gt; field so that the next object starts at the correct address.&lt;/p&gt;

&lt;p&gt;The second base, &lt;code&gt;Parent2&lt;/code&gt;, starts exactly at byte 16—this is the very offset we've seen in the code (&lt;code&gt;p2 != d&lt;/code&gt;). It also receives 8 bytes for its own virtual pointer and 4 bytes for data. The structure ends with the &lt;code&gt;res&lt;/code&gt; field of the &lt;code&gt;Derived&lt;/code&gt; class. The final object size is 32 bytes, even though the sum of useful data and pointers gives only 28. The extra 4 bytes are added at the end to comply with the &lt;code&gt;align=8&lt;/code&gt; rule. The entire object must be a multiple of its most stringent member—the 8-byte pointer.&lt;/p&gt;

&lt;p&gt;Let's see what other surprises alignment may have in store.&lt;/p&gt;

&lt;h4&gt;
  
  
  Casting to void*
&lt;/h4&gt;

&lt;p&gt;Let's go over a situation that often comes up when working with low-level code. We need to pass the complex &lt;code&gt;Derived&lt;/code&gt; object to the callback function via a raw &lt;code&gt;void*&lt;/code&gt; pointer. So, we pack it into an unaddressed container. Then, in the handler, we try to extract it back as the &lt;code&gt;Parent2&lt;/code&gt; base class. At first, it seems simple, but not when it comes to virtual inheritance. Let's complete the previous code fragment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;process_callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;raw_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Parent2&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;broken_p2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Parent2&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;raw_data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"--- The result of a void cast ---"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Original void* address: "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;raw_data&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Broken Parent2 address: "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;broken_p2&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;" (Not offset)"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;
&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look at the program output.&lt;/p&gt;

&lt;p&gt;
  Program output
  &lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="o"&gt;---&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;cast&lt;/span&gt; &lt;span class="o"&gt;---&lt;/span&gt;
&lt;span class="n"&gt;Original&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;0x5baf237792b0&lt;/span&gt;
&lt;span class="n"&gt;Broken&lt;/span&gt; &lt;span class="n"&gt;Parent2&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;0x5baf237792b0&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Not&lt;/span&gt; &lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;/p&gt;

&lt;p&gt;When we run this code, we'll see that &lt;code&gt;broken_p2&lt;/code&gt; points to the same address as the start of the entire object, even though the &lt;code&gt;Parent2&lt;/code&gt; data is offset in memory. &lt;code&gt;void*&lt;/code&gt; completely "blinds" the compiler, erasing all information about subobjects' location. When attempting to restore &lt;code&gt;Parent2*&lt;/code&gt; directly from &lt;code&gt;void&lt;/code&gt;, the compiler incorrectly interprets that the data for this parent starts right at the &lt;code&gt;void*&lt;/code&gt;address. In reality, &lt;code&gt;Parent2&lt;/code&gt; is separated from the object start by service pointers and alignment bytes.&lt;/p&gt;

&lt;p&gt;As a result, &lt;code&gt;broken_p2&lt;/code&gt; becomes invalid: it ignores the necessary pointer adjustment, and any attempt to read a field returns garbage. The whole mechanism relies on precise byte calculations and technical padding. Casting through &lt;code&gt;void*&lt;/code&gt; ignores these gaps, causing the program to read data with a shift.&lt;/p&gt;

&lt;p&gt;How can we fix this? We need the compiler to see the correct offsets again. To do this, the pointer has to be restored in stages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;process_callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;raw_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Parent2&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;broken_p2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Parent2&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;raw_data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

  &lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;restored_d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;raw_data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;Parent2&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;safe_p2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;restored_d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"--- The result of a void cast ---"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Original void* address: "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;raw_data&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Broken Parent2 address: "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;broken_p2&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;" (Not offset)"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Safe Parent2 address: "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;safe_p2&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;" (Offset)"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of attempting a direct leap from untyped memory straight to a base class, we should first return the pointer to its original full type—&lt;code&gt;Derived*&lt;/code&gt;. At this stage, the compiler restores the memory layout context of the entire object. It again sees the boundaries of all subobjects, the presence of service pointers, and the current offset tables. Only then, upon the next cast to &lt;code&gt;Parent2*&lt;/code&gt;, does the pointer adjustment mechanism activate. The compiler refers to the type metadata (including the &lt;code&gt;vbtable&lt;/code&gt; in the case of virtual inheritance), takes alignment requirements into account, and calculates the final effective address of the needed data segment.&lt;/p&gt;

&lt;p&gt;
  Full code fragment
  &lt;br&gt;
&lt;a href="https://godbolt.org/z/ehcW9YMYr" rel="noopener noreferrer"&gt;Compiler Explorer&lt;/a&gt;&lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt;  &lt;span class="cpf"&gt;&amp;lt;cstring&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Parent1&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;Parent1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Parent2&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;num2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;Parent2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; 
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Parent1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Parent2&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;process_callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;raw_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Parent2&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;broken_p2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Parent2&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;raw_data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

  &lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;restored_d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;raw_data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;Parent2&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;safe_p2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;restored_d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"--- The result of a void cast ---"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Original void* address: "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;raw_data&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Broken Parent2 address: "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;broken_p2&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;" (Not offset)"&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Safe Parent2 address: "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;safe_p2&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;" (Offset)"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;process_callback&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;/p&gt;

&lt;h4&gt;
  
  
  Empty Base Optimization with virtual
&lt;/h4&gt;

&lt;p&gt;In the first part we covered Empty Base Optimization (EBO). By the standard, the size of any object can't be zero, so even a completely empty class takes 1 byte in memory. In ordinary inheritance, the compiler can collapse that byte so that the empty base class doesn't bloat the derived class size. We do remember that. But as soon as virtuality enters the hierarchy, this optimization fails.&lt;/p&gt;

&lt;p&gt;Here comes a spoiler alert: Clang worked wonders with optimization and managed to &lt;a href="https://godbolt.org/z/48qafE6hh" rel="noopener noreferrer"&gt;optimize everything&lt;/a&gt;. It places all empty classes at offset zero, effectively hiding them inside the &lt;code&gt;vtable&lt;/code&gt; pointer. So, for this example, we set Clang aside and turn to MSVC to take a look at this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Empty1&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Empty2&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Empty3&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Root&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Empty1&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Root1&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Empty2&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;r1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Root2&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Empty3&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;r2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Root1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Root2&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;symbol&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's check the size of the &lt;code&gt;Base&lt;/code&gt; class.&lt;/p&gt;

&lt;p&gt;
  Program output
  &lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;byte&lt;/span&gt;
&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;96&lt;/span&gt; &lt;span class="n"&gt;byte&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;/p&gt;

&lt;p&gt;We can put it like this:&lt;/p&gt;

&lt;p&gt;
  Compiler Explorer layout
  &lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt;  &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;96&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
  &lt;span class="o"&gt;+---&lt;/span&gt;
 &lt;span class="mi"&gt;0&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;vfptr&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="mi"&gt;8&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;vbptr&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="mi"&gt;16&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;
&lt;span class="mi"&gt;24&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;symbol&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;alignment&lt;/span&gt; &lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;alignment&lt;/span&gt; &lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;alignment&lt;/span&gt; &lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;+---&lt;/span&gt;
  &lt;span class="o"&gt;+---&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="n"&gt;Empty1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;+---&lt;/span&gt;
  &lt;span class="o"&gt;+---&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="n"&gt;Root&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mi"&gt;32&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;vbptr&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="mi"&gt;40&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;alignment&lt;/span&gt; &lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;+---&lt;/span&gt;
  &lt;span class="o"&gt;+---&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="n"&gt;Empty2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;+---&lt;/span&gt;
  &lt;span class="o"&gt;+---&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="n"&gt;Root1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mi"&gt;56&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;vbptr&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="mi"&gt;64&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;r1&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;alignment&lt;/span&gt; &lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;+---&lt;/span&gt;
  &lt;span class="o"&gt;+---&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="n"&gt;Empty3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;+---&lt;/span&gt;
  &lt;span class="o"&gt;+---&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="n"&gt;Root2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mi"&gt;80&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;vbptr&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="mi"&gt;88&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;r2&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;alignment&lt;/span&gt; &lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;+---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;/p&gt;

&lt;p&gt;The object has bloated to 96 bytes, even though its useful payload barely reaches a third of that volume. At the object's start we see the standard "head": 8 bytes for the &lt;code&gt;vfptr&lt;/code&gt; (pointer to the function table) and another 8 bytes for the &lt;code&gt;vbptr&lt;/code&gt; (pointer to the base table). Then comes the data &lt;code&gt;double X&lt;/code&gt;, which due to its size imposes strict 8-byte alignment on the entire structure. But the most interesting part begins after the &lt;code&gt;char symbol&lt;/code&gt; field. Instead of packing data more tightly, the compiler inserts massive blocks of alignment members (technical &lt;code&gt;voids&lt;/code&gt; of 7 and 4 bytes) to make sure that each following virtual base starts strictly on a clean eight-byte boundary.&lt;/p&gt;

&lt;p&gt;The object turns into a chain of virtual databases (&lt;code&gt;Root&lt;/code&gt;, &lt;code&gt;Root1&lt;/code&gt;, &lt;code&gt;Root2&lt;/code&gt;), each of them comes at a high cost. Instead of collapsing &lt;code&gt;Empty&lt;/code&gt;classes as Clang did, MSVC allocates a separate &lt;code&gt;vbptr&lt;/code&gt; for each navigation branch. As a result, each such section consumes 16 to 24 bytes: 8 bytes for the service pointer, 4–8 bytes for the data, and a required padding to maintain symmetry.&lt;/p&gt;

&lt;p&gt;The net result is a structure where real variables literally drown in service pointers and gaps.&lt;/p&gt;

&lt;p&gt;
  Full code fragment
  &lt;br&gt;
&lt;a href="https://godbolt.org/z/8cb1MvnT4" rel="noopener noreferrer"&gt;Compiler Explorer&lt;/a&gt;&lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt;  &lt;span class="cpf"&gt;&amp;lt;cstring&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Empty1&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Empty2&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Empty3&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Root&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Empty1&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Root1&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Empty2&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;r1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Root2&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Empty3&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;r2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Root1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Root2&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
  &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;symbol&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"sizeof(Empty): "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Empty1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;" byte"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"sizeof(Base): "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;" byte"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance impact
&lt;/h2&gt;

&lt;p&gt;Having covered theory and examples, we should discuss the cost of virtual inheritance—specifically, how it affects processor performance through cache misses.&lt;/p&gt;

&lt;p&gt;We know that data location is crucial in system programming. The more tightly the fields are packed in memory, the higher the probability that the processor loads them into cache in a single fetch. Virtual inheritance, however, deliberately destroys this density. Since the virtual base subobject is forcibly placed at the very end of the layout, while its controlling &lt;code&gt;vbptr&lt;/code&gt; locates at the beginning, the data of one logical object becomes split across different cache lines. The processor must repeatedly access main memory, causing execution delays.&lt;/p&gt;

&lt;p&gt;On top of all that, there's also an issue of alignment. To ensure consistent pointer access, the compiler inserts extra empty bytes. We end up with an object with holes. When processing such objects, the processor is forced to use memory bus bandwidth to transfer unnecessary alignment bytes along with the useful data. As a result, the cache can't hold all the useful information.&lt;/p&gt;

&lt;p&gt;If we work with large arrays of data, things worsen even more. In an ordinary class, fields lie in a dense block, and the processor reads them in a single linear pass. With virtual inheritance, this integrity gets lost: the base class data is moved to the very end of the structure, while only a pointer to the offset table (&lt;code&gt;vbptr&lt;/code&gt;) remains at the beginning.&lt;/p&gt;

&lt;p&gt;So, to access any database field, the processor must first access the &lt;code&gt;vbptr&lt;/code&gt;, calculate the address using a table, and only then jump to the data itself at the end of the object. These constant computations and memory jumps between service pointers and scattered fields deprive the program of caching advantages and multiply array processing slowdowns.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is virtuality worth it?
&lt;/h2&gt;

&lt;p&gt;We see that using the word &lt;code&gt;virtual&lt;/code&gt; can easily bloat our object memory footprint, confuse our code, and introduce various errors. Here comes the question: why do we really need it?&lt;/p&gt;

&lt;p&gt;On the one hand, virtual inheritance and virtual functions are fundamental design tools. They enable designing flexible, extensible systems, and solve the diamond problem. In complex architectures, the convenience of polymorphism and clean hierarchies often outweighs the loss of a few dozen bytes. It helps us think in terms of abstractions rather than memory addresses.&lt;/p&gt;

&lt;p&gt;On the other hand, architectural flexibility comes at a hardware cost. As we've seen, virtuality transforms compact structures into bulky objects with memory holes. Also, double indirect addressing via the &lt;code&gt;vbtable&lt;/code&gt; can become a bottleneck in critical paths of game engines. Yet we wouldn't recommend abandoning this mechanism. In practice, context determines the choice.&lt;/p&gt;

&lt;p&gt;If the logic inside a virtual function is complex and lengthy, the microscopic delay of looking up an address in a table becomes negligible and simply dissolves in the overall execution time. Moreover, when it comes to a vast number of derived classes, attempting to replace polymorphism with manual type checking via &lt;code&gt;switch&lt;/code&gt; or &lt;code&gt;if-else&lt;/code&gt; often proves slower than a direct table jump. Alternatives like CRTP, which promise free static typing, quickly turn into unmaintainable monsters in multiple inheritance scenarios.&lt;/p&gt;

&lt;p&gt;In such hierarchies, standard virtuality remains the lesser evil, delivering clean code at an acceptable price. In the end, the choice between static and dynamic structure is always a search for balance.&lt;/p&gt;

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

&lt;p&gt;So, we've come a long way and made sure that virtuality and alignment are an inseparable pair that dictate the physical structure of an object. Understanding these mechanisms transforms abstract classes into a precise architectural layout, where every byte and every offset falls under engineering control. This enables us to strike a balance between the flexibility of dynamic polymorphism and execution efficiency.&lt;/p&gt;

&lt;p&gt;To ensure that your code remains under full control and that complex hierarchies create no hidden memory issues, you're welcome to use our &lt;a href="https://pvs-studio.com/en/pvs-studio/try-free/?utm_source=website&amp;amp;utm_medium=devto&amp;amp;utm_campaign=article&amp;amp;utm_content=1369" rel="noopener noreferrer"&gt;static analyzer&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>cpp</category>
      <category>compiling</category>
    </item>
    <item>
      <title>AI integrations: Rely or verify? Checking Semantic Kernel</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Thu, 23 Apr 2026 12:48:25 +0000</pubDate>
      <link>https://forem.com/pvsdev/ai-integrations-rely-or-verify-checking-semantic-kernel-1fnn</link>
      <guid>https://forem.com/pvsdev/ai-integrations-rely-or-verify-checking-semantic-kernel-1fnn</guid>
      <description>&lt;p&gt;Semantic Kernel is a Microsoft's SDK for integrating AI models into applications. Can PVS-Studio static analyzer find defects in the source code of a project like this? This article answers this question. Enjoy reading!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fweh79gx9pdbfono73dio.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fweh79gx9pdbfono73dio.png" alt="1367_semantic-kernel/image1.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Projects that involve AI integration increasingly shape everyday development. One such project is &lt;a href="https://github.com/microsoft/semantic-kernel" rel="noopener noreferrer"&gt;Semantic Kernel&lt;/a&gt;. It's an SDK for building AI agents and orchestrating LLM scenarios, and Microsoft actively develops it.&lt;/p&gt;

&lt;p&gt;But underneath even the most modern solutions, you'll find ordinary C# code—with all the usual problems that come with it. We'll try to confirm that today.&lt;/p&gt;

&lt;p&gt;To analyze the C# part of the project, we used &lt;a href="https://pvs-studio.com/en/pvs-studio/" rel="noopener noreferrer"&gt;PVS-Studio static analyzer version 7.41&lt;/a&gt;. The source code we checked corresponds to this &lt;a href="https://github.com/microsoft/semantic-kernel/tree/134e52e7540270ca4055bd5eab4d7606f9689ce1" rel="noopener noreferrer"&gt;commit&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Note that we'll only discuss the most interesting code snippets to keep the article concise.&lt;/p&gt;

&lt;p&gt;Let's start breaking down suspicious spots!&lt;/p&gt;

&lt;h2&gt;
  
  
  Misplaced priorities
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Code snippet 1&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; 
                &lt;span class="nf"&gt;CreateToolsAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;AgentDefinition&lt;/span&gt; &lt;span class="n"&gt;agentDefinition&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                 &lt;span class="n"&gt;BedrockAgent&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                                 &lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;cancellationToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;knowledgeBase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Options&lt;/span&gt;
                   &lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TryGetValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;KnowledgeBaseId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                                 &lt;span class="n"&gt;out&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt; 
                                                         &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;knowledgeBaseId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;as&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;knowledgeBase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Description&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AssociateAgentKnowledgeBaseAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;knowledgeBaseId&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                                                 &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                                 &lt;span class="n"&gt;cancellationToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
               &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConfigureAwait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v3177/" rel="noopener noreferrer"&gt;V3177&lt;/a&gt; The 'false' literal belongs to the '&amp;amp;&amp;amp;' operator with a higher priority. It is possible the literal was intended to belong to '??' operator instead. &lt;a href="https://github.com/microsoft/semantic-kernel/blob/134e52e7540270ca4055bd5eab4d7606f9689ce1/dotnet/src/Agents/Bedrock/Extensions/BedrockAgentDefinitionExtensions.cs#L44" rel="noopener noreferrer"&gt;BedrockAgentDefinitionExtensions.cs 44&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The developer likely intended this condition to work as follows: if &lt;code&gt;knowledgeBase.Options?.TryGetValue(KnowledgeBaseId, out var value)&lt;/code&gt; is not &lt;code&gt;null&lt;/code&gt; then check that &lt;code&gt;value is not null &amp;amp;&amp;amp; value is string&lt;/code&gt;. But the actual behavior differs. The &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; operator takes higher priority than &lt;code&gt;??&lt;/code&gt;, so the checks on &lt;code&gt;value&lt;/code&gt; never execute.&lt;/p&gt;

&lt;p&gt;Another clue that an error lurks here: the right operand of &lt;code&gt;??&lt;/code&gt;. It looks like &lt;code&gt;false &amp;amp;&amp;amp; value is not null &amp;amp;&amp;amp; value is string&lt;/code&gt;. The outcome of that expression is obvious. The condition contains only &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; operators, and one operand is &lt;code&gt;false&lt;/code&gt;. So, the entire expression is always &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To fix it, the author needs to add parentheses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;knowledgeBase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Options&lt;/span&gt;
                   &lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TryGetValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;KnowledgeBaseId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                                 &lt;span class="n"&gt;out&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt; 
                                                          &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that 4 other places in the source code contain the same issue:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/microsoft/semantic-kernel/blob/134e52e7540270ca4055bd5eab4d7606f9689ce1/dotnet/src/Plugins/Plugins.Web/Tavily/TavilyTextSearch.cs#L477" rel="noopener noreferrer"&gt;TavilyTextSearch.cs 477&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/microsoft/semantic-kernel/blob/134e52e7540270ca4055bd5eab4d7606f9689ce1/dotnet/src/Plugins/Plugins.Web/Tavily/TavilyTextSearch.cs#L505" rel="noopener noreferrer"&gt;TavilyTextSearch.cs 505&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/microsoft/semantic-kernel/blob/134e52e7540270ca4055bd5eab4d7606f9689ce1/dotnet/src/Plugins/Plugins.Web/Tavily/TavilyTextSearch.cs#L540" rel="noopener noreferrer"&gt;TavilyTextSearch.cs 540&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/microsoft/semantic-kernel/blob/134e52e7540270ca4055bd5eab4d7606f9689ce1/dotnet/src/Plugins/Plugins.Web/Tavily/TavilyTextSearch.cs#L574" rel="noopener noreferrer"&gt;TavilyTextSearch.cs 574&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Code snippet 2&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;RestApiParameterFilter&lt;/span&gt; &lt;span class="n"&gt;s_restApiParameterFilter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RestApiParameterFilterContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"me_sendMail"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Equals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Operation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                               &lt;span class="n"&gt;StringComparison&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OrdinalIgnoreCase&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
      &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"me_calendar_CreateEvents"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Equals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Operation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                            &lt;span class="n"&gt;StringComparison&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OrdinalIgnoreCase&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="s"&gt;"payload"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Equals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Parameter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                          &lt;span class="n"&gt;StringComparison&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OrdinalIgnoreCase&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Parameter&lt;/span&gt;
           &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TrimPropertiesFromRequestBody&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Parameter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Schema&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Parameter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Parameter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v3088/" rel="noopener noreferrer"&gt;V3088&lt;/a&gt; The expression was enclosed by parentheses twice: ((expression)). One pair of parentheses is unnecessary or misprint is present. &lt;a href="https://github.com/microsoft/semantic-kernel/blob/134e52e7540270ca4055bd5eab4d7606f9689ce1/dotnet/samples/Concepts/Plugins/CopilotAgentBasedPlugins.cs#L212" rel="noopener noreferrer"&gt;CopilotAgentBasedPlugins.cs 212&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The outermost parentheses wrap the entire &lt;code&gt;if&lt;/code&gt; condition, making them pointless. The developer probably intended this logic: apply the &lt;code&gt;payload&lt;/code&gt; parameter name check to both operations (&lt;code&gt;me_sendMail&lt;/code&gt; and &lt;code&gt;me_calendar_CreateEvents&lt;/code&gt;). But in reality, the &lt;code&gt;payload&lt;/code&gt; check applies only to the second operation because &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; has a higher priority than &lt;code&gt;||&lt;/code&gt;. To fix it, the developer needs to parenthesize only the checks for &lt;code&gt;me_sendMail&lt;/code&gt; and &lt;code&gt;me_calendar_CreateEvents&lt;/code&gt;, not the entire condition.&lt;/p&gt;

&lt;h2&gt;
  
  
  Forgot something
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Code snippet 3&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;GetAudioOutputMimeType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ChatAudioOptions&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;audioOptions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;audioOptions&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;audioOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OutputAudioFormat&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;ChatOutputAudioFormat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Wav&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"audio/wav"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;audioOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OutputAudioFormat&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;ChatOutputAudioFormat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Mp3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"audio/mp3"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;audioOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OutputAudioFormat&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;ChatOutputAudioFormat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Opus&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"audio/opus"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;audioOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OutputAudioFormat&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;ChatOutputAudioFormat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Wav&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"audio/wav"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;audioOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OutputAudioFormat&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;ChatOutputAudioFormat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Flac&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"audio/flac"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;audioOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OutputAudioFormat&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;ChatOutputAudioFormat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pcm16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"audio/pcm16"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;NotSupportedException&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="s"&gt;"Unsupported audio output format '{audioOptions.OutputAudioFormat}'. "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
    &lt;span class="s"&gt;"Supported formats are 'wav', 'mp3', 'opus', 'flac' and 'pcm16'."&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v3021/" rel="noopener noreferrer"&gt;V3021&lt;/a&gt; There are two 'if' statements with identical conditional expressions. The first 'if' statement contains method return. This means that the second 'if' statement is senseless &lt;a href="https://github.com/microsoft/semantic-kernel/blob/134e52e7540270ca4055bd5eab4d7606f9689ce1/dotnet/src/Connectors/Connectors.OpenAI/Core/ClientCore.ChatCompletion.cs#L985" rel="noopener noreferrer"&gt;ClientCore.ChatCompletion.cs 985&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;GetAudioOutputMimeType&lt;/code&gt; method contains the same check twice: &lt;code&gt;audioOptions.OutputAudioFormat == ChatOutputAudioFormat.Wav&lt;/code&gt;. The repeated check for &lt;code&gt;ChatOutputAudioFormat.Wav&lt;/code&gt; is unreachable code—the method returns when the first match occurs. This is a typical copy-paste error.&lt;/p&gt;

&lt;p&gt;Interestingly, the &lt;code&gt;ChatOutputAudioFormat&lt;/code&gt; struct declares a &lt;code&gt;ChatOutputAudioFormat Aac&lt;/code&gt; format. This is the only format the &lt;code&gt;GetAudioOutputMimeType&lt;/code&gt; method doesn't handle. Perhaps it should replace one of the &lt;code&gt;audioOptions.OutputAudioFormat == ChatOutputAudioFormat.Wav&lt;/code&gt; check.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;ChatOutputAudioFormat&lt;/span&gt; 
                                 &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IEquatable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ChatOutputAudioFormat&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;ChatOutputAudioFormat&lt;/span&gt; &lt;span class="n"&gt;Wav&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChatOutputAudioFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WavValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;ChatOutputAudioFormat&lt;/span&gt; &lt;span class="n"&gt;Aac&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;        &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChatOutputAudioFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AacValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;ChatOutputAudioFormat&lt;/span&gt; &lt;span class="n"&gt;Mp3&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChatOutputAudioFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Mp3Value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;ChatOutputAudioFormat&lt;/span&gt; &lt;span class="n"&gt;Flac&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChatOutputAudioFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FlacValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;ChatOutputAudioFormat&lt;/span&gt; &lt;span class="n"&gt;Opus&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChatOutputAudioFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OpusValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;ChatOutputAudioFormat&lt;/span&gt; &lt;span class="n"&gt;Pcm16&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChatOutputAudioFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pcm16Value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Code snippet 4&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;KernelSearchResults&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TextSearchResult&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;GetTextSearchResultsAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                                &lt;span class="n"&gt;TextSearchOptions&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;searchOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                &lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;cancellationToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;searchResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SearchInternalAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                                                    &lt;span class="n"&gt;searchOptions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                                                    &lt;span class="n"&gt;cancellationToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                               &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConfigureAwait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
   &lt;span class="n"&gt;searchResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; 
      &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;TextSearchResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SourceName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Link&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SourceLink&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; 
    &lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;searchResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;TextSearchResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SourceName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Link&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SourceLink&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="n"&gt;ToAsyncEnumerable&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v3220/" rel="noopener noreferrer"&gt;V3220&lt;/a&gt; The result of the 'Select' LINQ method with deferred execution is never used. The method will not be executed. &lt;a href="https://github.com/microsoft/semantic-kernel/blob/134e52e7540270ca4055bd5eab4d7606f9689ce1/dotnet/src/SemanticKernel.Core/Data/TextSearchStore/TextSearchStore.cs#L204" rel="noopener noreferrer"&gt;TextSearchStore.cs 204&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;results&lt;/code&gt; variable receives the result of a LINQ method call, but the variable is never used after that. Many LINQ methods have &lt;a href="https://learn.microsoft.com/en-us/dotnet/csharp/linq/get-started/introduction-to-linq-queries#deferred" rel="noopener noreferrer"&gt;deferred execution&lt;/a&gt;. So, value obtained from the LINQ expression is not evaluated when forming that expression. It will be evaluated only when we iterate over the resulting sequence (for example, in a &lt;code&gt;foreach&lt;/code&gt; loop).&lt;/p&gt;

&lt;p&gt;The value assignment to &lt;code&gt;results&lt;/code&gt; is followed by a &lt;code&gt;return&lt;/code&gt; statement with a similar LINQ expression. Most likely, one of the LINQ expressions is redundant. The author should either remove the &lt;code&gt;results&lt;/code&gt; variable or use it when forming the return value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToAsyncEnumerable&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Code snippet 5&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;/// Creates a new instance of the &amp;lt;see cref="KernelProcess"/&amp;gt; class.&lt;/span&gt;
&lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;/// &amp;lt;param name="state"&amp;gt;The process state.&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;/// &amp;lt;param name="steps"&amp;gt;The steps of the process.&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;/// &amp;lt;param name="edges"&amp;gt;The edges of the process.&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;/// &amp;lt;param name="threads"&amp;gt;The threads associated with the process.&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;KernelProcess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
           &lt;span class="n"&gt;KernelProcessState&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
           &lt;span class="n"&gt;IList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;KernelProcessStepInfo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="n"&gt;Dictionary&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;KernelProcessEdge&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;?&lt;/span&gt; &lt;span class="n"&gt;edges&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
           &lt;span class="n"&gt;IReadOnlyDictionary&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                               &lt;span class="n"&gt;KernelProcessAgentThread&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;?&lt;/span&gt; &lt;span class="n"&gt;threads&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;KernelProcess&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;edges&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Verify&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NotNull&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;Verify&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NotNullOrWhiteSpace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Steps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[..&lt;/span&gt; &lt;span class="n"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v3117/" rel="noopener noreferrer"&gt;V3117&lt;/a&gt; Constructor parameter 'threads' is not used. &lt;a href="https://github.com/microsoft/semantic-kernel/blob/134e52e7540270ca4055bd5eab4d7606f9689ce1/dotnet/src/Experimental/Process.Abstractions/KernelProcess.cs#L46" rel="noopener noreferrer"&gt;KernelProcess.cs 46&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;threads&lt;/code&gt; parameter wasn't used. When calling the &lt;code&gt;KernelProcess&lt;/code&gt; method, the caller may pass an argument matching &lt;code&gt;threads&lt;/code&gt;. That suggests the caller expects the parameter to be used. &lt;/p&gt;

&lt;p&gt;Note that the &lt;code&gt;KernelProcess&lt;/code&gt; class has a property named &lt;code&gt;Threads&lt;/code&gt;. Perhaps that property should initialize from the unused parameter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Array index out of bounds
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Code snippet 6&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;ComputeTruncationIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                     &lt;span class="n"&gt;IReadOnlyList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ChatMessageContent&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;chatHistory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                     &lt;span class="n"&gt;ChatMessageContent&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;systemMessage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;truncationIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;totalTokenCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;systemMessage&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Metadata&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"TokenCount"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chatHistory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                        &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;truncationIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;tokenCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;chatHistory&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;Metadata&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"TokenCount"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tokenCount&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;totalTokenCount&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_maxTokenCount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;totalTokenCount&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;tokenCount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Skip function related content&lt;/span&gt;
  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;truncationIndex&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;chatHistory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                             &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chatHistory&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;truncationIndex&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;Items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;FunctionCallContent&lt;/span&gt; 
                                                      &lt;span class="n"&gt;or&lt;/span&gt; &lt;span class="n"&gt;FunctionResultContent&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;truncationIndex&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;truncationIndex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v3106/" rel="noopener noreferrer"&gt;V3106&lt;/a&gt; Possible negative index value. The value of 'truncationIndex' index could reach -1. &lt;a href="https://github.com/microsoft/semantic-kernel/blob/134e52e7540270ca4055bd5eab4d7606f9689ce1/dotnet/samples/Concepts/ChatCompletion/ChatHistoryReducers/ChatHistoryMaxTokensReducer.cs#L75" rel="noopener noreferrer"&gt;ChatHistoryMaxTokensReducer.cs 75&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;truncationIndex&lt;/code&gt; variable initializes to &lt;code&gt;-1&lt;/code&gt;. If the &lt;code&gt;chatHistory&lt;/code&gt; collection is empty, the execution flow won't enter the &lt;code&gt;for&lt;/code&gt; loop as the condition &lt;code&gt;-1 &amp;gt;= 0&lt;/code&gt; fails before the first iteration. Thus, the value of &lt;code&gt;truncationIndex&lt;/code&gt; doesn't change. Immediately after the &lt;code&gt;for&lt;/code&gt; loop comes a &lt;code&gt;while&lt;/code&gt; loop whose condition will be true if &lt;code&gt;chatHistory&lt;/code&gt; has zero elements (&lt;code&gt;-1 &amp;lt; 0&lt;/code&gt;). Inside the &lt;code&gt;while&lt;/code&gt; loop, the code uses &lt;code&gt;truncationIndex&lt;/code&gt; as an index, and it may still be &lt;code&gt;-1&lt;/code&gt;. Accessing an element with a negative index throws an &lt;code&gt;IndexOutOfRangeException&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To fix this, the developer should check that the index is not negative before using it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Issues with null
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Code snippet 7&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;KernelProcessProxy&lt;/span&gt; &lt;span class="nf"&gt;ToKernelProcessProxy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;KernelProcessStepInfo&lt;/span&gt; &lt;span class="n"&gt;processStepInfo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToKernelProcessStepInfo&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;KernelProcessStepState&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;KernelException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="s"&gt;"Unable to read state from proxy with name "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
                              &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="s"&gt;"'{this.State.Name}', Id '{this.State.Id}' "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
                              &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="s"&gt;"and type {this.State.GetType()}."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;KernelProcessProxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Edges&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ProxyMetadata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ProxyMetadata&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;required&lt;/span&gt; &lt;span class="n"&gt;KernelProcessStepState&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v3080/" rel="noopener noreferrer"&gt;V3080&lt;/a&gt; [SEC-NULL] Possible null dereference. Consider inspecting 'this.State'. &lt;a href="https://github.com/microsoft/semantic-kernel/blob/134e52e7540270ca4055bd5eab4d7606f9689ce1/dotnet/src/Experimental/Process.Runtime.Dapr/DaprProxyInfo.cs#L30" rel="noopener noreferrer"&gt;DaprProxyInfo.cs 30&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The condition checks that &lt;code&gt;this.State&lt;/code&gt; does not match the&lt;code&gt;KernelProcessStepState&lt;/code&gt; type. The &lt;code&gt;State&lt;/code&gt; property declaration indicates that its type is &lt;code&gt;KernelProcessStepState&lt;/code&gt;. So the condition seems always false? Not exactly. If &lt;code&gt;this.State&lt;/code&gt; is &lt;code&gt;null&lt;/code&gt;, then &lt;code&gt;this.State is not KernelProcessStepState&lt;/code&gt; will be &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We expect a &lt;code&gt;KernelException&lt;/code&gt; in the &lt;code&gt;then&lt;/code&gt; block of the &lt;code&gt;if&lt;/code&gt; statement. But the actual behavior differes. The exception message accesses properties of &lt;code&gt;this.State&lt;/code&gt;. The only way execution flow reaches the &lt;code&gt;then&lt;/code&gt; block is when &lt;code&gt;this.State&lt;/code&gt; is &lt;code&gt;null&lt;/code&gt;, the result will be a &lt;code&gt;NullReferenceException&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code snippet 8&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;RestApiPayload&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; 
                  &lt;span class="n"&gt;CreateRestApiOperationPayload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;operationId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                                &lt;span class="n"&gt;OpenApiRequestBody&lt;/span&gt; &lt;span class="n"&gt;requestBody&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requestBody&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;mediaType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GetMediaType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requestBody&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
            &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;KernelException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
               &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="s"&gt;"Neither of the media types of {operationId} is supported."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;mediaTypeMetadata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requestBody&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;mediaType&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

  &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;payloadProperties&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GetPayloadProperties&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;operationId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                                               &lt;span class="n"&gt;mediaTypeMetadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Schema&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RestApiPayload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mediaType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="n"&gt;payloadProperties&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="n"&gt;requestBody&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="n"&gt;mediaTypeMetadata&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Schema&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToJsonSchema&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;   &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v3095/" rel="noopener noreferrer"&gt;V3095&lt;/a&gt; The 'mediaTypeMetadata' object was used before it was verified against null. Check lines: 464, 466. &lt;a href="https://github.com/microsoft/semantic-kernel/blob/134e52e7540270ca4055bd5eab4d7606f9689ce1/dotnet/src/Functions/Functions.OpenApi/OpenApi/OpenApiDocumentParser.cs#L464" rel="noopener noreferrer"&gt;OpenApiDocumentParser.cs 464&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;mediaTypeMetadata&lt;/code&gt; variable is fisrt accessed without a &lt;code&gt;null&lt;/code&gt; check, and then on the very next line is checked using a null-conditional operator &lt;code&gt;?.&lt;/code&gt;. Perhaps the check in the second case is redundant, and authors should remove it. If &lt;code&gt;mediaTypeMetadata&lt;/code&gt; can indeed be &lt;code&gt;null&lt;/code&gt;, then the first access will result in a &lt;code&gt;NullReferenceException&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code snippet 9&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;internal&lt;/span&gt; &lt;span class="n"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ReActStep&lt;/span&gt;&lt;span class="o"&gt;?&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;GetNextStepAsync&lt;/span&gt;&lt;span class="p"&gt;(....)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsEnabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LogLevel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Information&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;                       &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"question: {Question}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"functionDescriptions: {FunctionDescriptions}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                 &lt;span class="n"&gt;functionDesc&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Scratchpad: {ScratchPad}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;scratchPad&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;llmResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_reActFunction&lt;/span&gt;
                              &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InvokeAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kernel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                              &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConfigureAwait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;llmResponseText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llmResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetValue&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsEnabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LogLevel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Debug&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LogDebug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Response : {ActionText}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;llmResponseText&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v3095/" rel="noopener noreferrer"&gt;V3095&lt;/a&gt; The 'this._logger' object was used before it was verified against null. Check lines: 144, 146. &lt;a href="https://github.com/microsoft/semantic-kernel/blob/134e52e7540270ca4055bd5eab4d7606f9689ce1/dotnet/src/Experimental/Orchestration.Flow/Execution/ReActEngine.cs#L144" rel="noopener noreferrer"&gt;ReActEngine.cs 144&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This case resembles the previous example. In the same context, the &lt;code&gt;this._logger&lt;/code&gt;field is used with a &lt;code&gt;null&lt;/code&gt; check and without it. Besides the code above, the &lt;code&gt;GetNextStepAsync&lt;/code&gt; method contains two more places where &lt;code&gt;this._logger&lt;/code&gt; is not checked for &lt;code&gt;null&lt;/code&gt;. As before, this indicates inconsistent handling of a potential &lt;code&gt;null&lt;/code&gt; value for&lt;code&gt;this._logger&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code snippet 10&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="n"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MAAI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AgentRunResponse&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 
                         &lt;span class="n"&gt;RunAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ChatMessage&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                                  &lt;span class="n"&gt;MAAI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AgentThread&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="kr"&gt;thread&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                  &lt;span class="n"&gt;MAAI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AgentRunOptions&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                  &lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;cancellationToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;  
  &lt;span class="p"&gt;....&lt;/span&gt;
  &lt;span class="n"&gt;AgentResponseItem&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ChatMessageContent&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;?&lt;/span&gt; &lt;span class="n"&gt;lastResponseItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
  &lt;span class="n"&gt;ChatMessage&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;lastResponseMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                              &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;

  &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="n"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;responseItem&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="p"&gt;....)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;lastResponseItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;responseItem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;MAAI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AgentRunResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;responseMessages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;AgentId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_innerAgent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;RawRepresentation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lastResponseItem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;AdditionalProperties&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lastResponseMessage&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AdditionalProperties&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
    &lt;span class="n"&gt;CreatedAt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lastResponseMessage&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreatedAt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                         &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warnings:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/docs/warnings/v3022/" rel="noopener noreferrer"&gt;V3022&lt;/a&gt; Expression 'lastResponseMessage' is always null. The operator '?.' is meaningless. &lt;a href="https://github.com/microsoft/semantic-kernel/blob/134e52e7540270ca4055bd5eab4d7606f9689ce1/dotnet/src/Agents/Abstractions/AIAgent/SemanticKernelAIAgent.cs#L111" rel="noopener noreferrer"&gt;SemanticKernelAIAgent.cs 111&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/docs/warnings/v3022/" rel="noopener noreferrer"&gt;V3022&lt;/a&gt; Expression 'lastResponseMessage' is always null. The operator '?.' is meaningless. &lt;a href="https://github.com/microsoft/semantic-kernel/blob/134e52e7540270ca4055bd5eab4d7606f9689ce1/dotnet/src/Agents/Abstractions/AIAgent/SemanticKernelAIAgent.cs#L112" rel="noopener noreferrer"&gt;SemanticKernelAIAgent.cs 112&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;lastResponseMessage&lt;/code&gt; variable initializes to &lt;code&gt;null&lt;/code&gt;. The code then uses its properties to initialize &lt;code&gt;AdditionalProperties&lt;/code&gt; and &lt;code&gt;CreatedAt&lt;/code&gt; of a new object. Turns out, those properties will always initialize to &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Perhaps by the time of &lt;code&gt;AdditionalProperties&lt;/code&gt; and &lt;code&gt;CreatedAt&lt;/code&gt; initialization, &lt;code&gt;lastResponseMessage&lt;/code&gt; should contain a non-null value. If the intention is to assign &lt;code&gt;null&lt;/code&gt; to these properties, then authors can remove &lt;code&gt;lastResponseMessage&lt;/code&gt;, as it only appears in the shown snippets.&lt;/p&gt;

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

&lt;p&gt;Our analysis of the C# portion of Semantic Kernel shows the expected picture: despite the project high profile and Microsoft involvement, the code contains typical issues. This is not unusual—complex systems under active development almost always contain questionable spots and various defects.&lt;/p&gt;

&lt;p&gt;If you'd like to analyze your own project with PVS-Studio, you can try the analyzer via this &lt;a href="https://pvs-studio.com/en/pvs-studio/try-free/?utm_source=website&amp;amp;utm_medium=devto&amp;amp;utm_campaign=article&amp;amp;utm_content=1367" rel="noopener noreferrer"&gt;link&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>csharp</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Webinar: Let's make a programming language. Grammars—Key points</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Wed, 22 Apr 2026 13:58:49 +0000</pubDate>
      <link>https://forem.com/pvsdev/webinar-lets-make-a-programming-language-grammars-key-points-50k1</link>
      <guid>https://forem.com/pvsdev/webinar-lets-make-a-programming-language-grammars-key-points-50k1</guid>
      <description>&lt;p&gt;PVS-Studio continues a series of webinars on how to create your own programming language using C++.&lt;/p&gt;

&lt;p&gt;Previously, we discussed what a programming language is and its overall structure. This time, the talk host, Yuri Minaev, went a level deeper—into grammars.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's the talk about?
&lt;/h2&gt;

&lt;p&gt;A grammar consists of terminal and non-terminal symbols, production rules, and a starting point. Non-terminals define higher-level constructs in terms of other symbols, while terminals represent basic, indivisible elements like digits or characters.&lt;/p&gt;

&lt;p&gt;Yuri explains how the way you design grammar determines how expressions are parsed and evaluated, including the associativity and priority of operations. He also introduces recursive definitions and explains how they form tree-like structures during parsing.&lt;/p&gt;

&lt;p&gt;The webinar wraps up by connecting grammar theory to actual implementation, describing recursive descent parsing as a flexible and an easy to implement approach. It mirrors the grammar structure through functions, enabling the parser to process input from the top down and construct meaning step by step.&lt;/p&gt;

&lt;p&gt;Learn more: &lt;a href="https://pvs-studio.com/en/blog/posts/1364/" rel="noopener noreferrer"&gt;How do compilers work?&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Want more?
&lt;/h2&gt;

&lt;p&gt;If you want to learn more and see the whole webinar, &lt;a href="https://pvs-studio.com/en/blog/video/11644/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=webinar&amp;amp;utm_content=web3" rel="noopener noreferrer"&gt;follow this link&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;You can also sign up for the next webinar in the series: &lt;a href="https://pvs-studio.com/en/webinar/27/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=webinar&amp;amp;utm_content=web3" rel="noopener noreferrer"&gt;Let's make a programming language. Lexer&lt;/a&gt;. During the webinar, Yuri will walk you through what a lexer is and how it's actually implemented in code.&lt;/p&gt;

&lt;p&gt;Don't worry if you missed our previous webinar sessions! You can watch them on our YouTube channel or website as well.&lt;/p&gt;

&lt;p&gt;We hope to see you there!&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>programming</category>
      <category>webinar</category>
      <category>softwaredevelopment</category>
    </item>
  </channel>
</rss>
