<?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>Developing new static analyzer: PVS-Studio JavaScript</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Wed, 15 Apr 2026 13:00:03 +0000</pubDate>
      <link>https://forem.com/pvsdev/developing-new-static-analyzer-pvs-studio-javascript-3h4o</link>
      <guid>https://forem.com/pvsdev/developing-new-static-analyzer-pvs-studio-javascript-3h4o</guid>
      <description>&lt;p&gt;PVS-Studio static code analyzer has been on the market for 18 years now. Over this time, it has grown to support C, C++, C#, and Java. We don't plan to stop at these languages. This article covers the development of a new JavaScript/TypeScript analyzer, which we release very soon.&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%2Fw9762vyqxxa5ljyo5shb.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%2Fw9762vyqxxa5ljyo5shb.png" alt="1363_JavaScript_analyzer/image1.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Given the enduring popularity of the ECMAScript language family among programmers, supporting an analyzer for one of the most popular language stacks was only a matter of time. As a stack grows in popularity, so does its ecosystem, and in the case of JavaScript/TypeScript, that ecosystem is the envy of many. As a programmer friend once said: "If you face some problem, there's already a library for JavaScript that solves it."&lt;/p&gt;

&lt;p&gt;Competition from both paid and free tools is fierce. So, our goal now is to build a stable and reliable platform that we can steadily develop and expand, eventually catching up to other market solutions. That is one reason we intend to release early: the EAP has &lt;a href="https://pvs-studio.com/en/blog/posts/js/1351/" rel="noopener noreferrer"&gt;already started&lt;/a&gt;, and the MVP release of the analyzer is scheduled for this August.&lt;/p&gt;

&lt;p&gt;In this article, we explain how the new analyzer works and what new architectural solutions we applied.&lt;/p&gt;

&lt;h2&gt;
  
  
  Language model
&lt;/h2&gt;

&lt;h3&gt;
  
  
  TypeScript tree
&lt;/h3&gt;

&lt;p&gt;Every analyzer starts with a language model—more specifically, with an &lt;a href="https://pvs-studio.com/en/blog/terms/0004/" rel="noopener noreferrer"&gt;abstract syntax tree&lt;/a&gt;. After all, the analyzer needs some way to work with source code.&lt;/p&gt;

&lt;p&gt;We began by tackling this very problem. The choice was clear: as we want both a syntax tree and a semantic model for JavaScript and TypeScript at the same time—plus support from the language developers—the TypeScript compiler has no competition. It can parse both languages, and its support is guaranteed as long as TypeScript itself evolves.&lt;/p&gt;

&lt;p&gt;Look at the resulting AST using the factorial function as an 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;function&lt;/span&gt; &lt;span class="nf"&gt;factorial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;let&lt;/span&gt; &lt;span class="n"&gt;result&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;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;let&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&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;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;n&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="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;result&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;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&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;For this, we get the following tree (see the spoiler).&lt;/p&gt;

&lt;p&gt;
  AST for factorial
  &lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="nl"&gt;SourceFile:&lt;/span&gt;
  &lt;span class="n"&gt;FunctionDeclaration&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;Identifier&lt;/span&gt;
    &lt;span class="n"&gt;Parameter&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;Identifier&lt;/span&gt;
    &lt;span class="n"&gt;Block&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;VariableStatement&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;VariableDeclarationList&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
          &lt;span class="n"&gt;VariableDeclaration&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;Identifier&lt;/span&gt;
            &lt;span class="n"&gt;NumericLiteral&lt;/span&gt;
      &lt;span class="n"&gt;ForStatement&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;VariableDeclarationList&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
          &lt;span class="n"&gt;VariableDeclaration&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;Identifier&lt;/span&gt;
            &lt;span class="n"&gt;NumericLiteral&lt;/span&gt;
      &lt;span class="n"&gt;BinaryExpression&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;Identifier&lt;/span&gt;
        &lt;span class="n"&gt;LessThanEqualsToken&lt;/span&gt;
        &lt;span class="n"&gt;Identifier&lt;/span&gt;
      &lt;span class="n"&gt;PostfixUnaryExpression&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;Identifier&lt;/span&gt;
      &lt;span class="n"&gt;Block&lt;/span&gt;
        &lt;span class="n"&gt;ExpressionStatement&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
          &lt;span class="n"&gt;BinaryExpression&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;Identifier&lt;/span&gt;
            &lt;span class="n"&gt;AsteriskEqualsToken&lt;/span&gt;
            &lt;span class="n"&gt;Identifier&lt;/span&gt;
      &lt;span class="n"&gt;ReturnStatement&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;Identifier&lt;/span&gt;
  &lt;span class="n"&gt;EndOfFileToken&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;/p&gt;

&lt;p&gt;You can play with it yourself &lt;a href="https://ts-ast-viewer.com/#code/GYVwdgxgLglg9mABMAhtOAnGKA2AKMASkQG8AoRRHAUykQ2oGcQc6BeRARgG4LlNEeGnRiIOAJm6JRAHg5gpMANRLi5SpQbNWiAFQcYvSgF8+DKCAxItLKL2NA" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;You may also notice small differences between this AST and more "academic" ones. First, the tree contains tokens, even though tokens usually belong to a parse tree. Second, their names reflect visual representation rather than semantic meaning. In the example above, we have &lt;code&gt;AsteriskEqualsToken&lt;/code&gt;, but the TypeScript compiler also has a token with the wonderful name &lt;code&gt;DotDotDotToken&lt;/code&gt; for the spread operator. &lt;/p&gt;

&lt;h3&gt;
  
  
  Semantics
&lt;/h3&gt;

&lt;p&gt;A syntax tree alone is not enough. Let's say we want to catch a missed assignment when replacing a character in a string:&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;function&lt;/span&gt; &lt;span class="n"&gt;replaceFoo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;variable&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="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;variable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"foo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"bar"&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;variable&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the result of &lt;code&gt;replace&lt;/code&gt; isn't saved anywhere. The analyzer could issue a warning about every &lt;code&gt;replace&lt;/code&gt; in the program, but that would produce too many &lt;a href="https://pvs-studio.com/en/blog/terms/6461/" rel="noopener noreferrer"&gt;false positives&lt;/a&gt;. To ensure that this is the &lt;code&gt;replace&lt;/code&gt; we need, we have to verify that it is called on an object of the needed type and that the argument types match the parameter types.&lt;/p&gt;

&lt;p&gt;How do we find out the type of the &lt;code&gt;variable&lt;/code&gt; identifier? Manually looking up definitions for every identifier node is overkill, and outside such simple cases it's non-trivial—with &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Hoisting" rel="noopener noreferrer"&gt;hoisting&lt;/a&gt; it would be much more complicated. &lt;/p&gt;

&lt;p&gt;This is where semantic code analysis comes in, helping us find variable types and scopes. And that's another reason we chose the TypeScript compiler. It can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;resolve identifiers and their types for TypeScript;&lt;/li&gt;
&lt;li&gt;resolve identifiers and infer types for JavaScript when possible—when a literal was explicitly assigned or JSDoc was used.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, the compiler really has everything we need. Still, the adventure is just beginning.&lt;/p&gt;

&lt;h3&gt;
  
  
  gRPC
&lt;/h3&gt;

&lt;p&gt;The Java team was assigned to develop the new analyzer. Perhaps it's because JavaScript matches Java by 50%. Just kidding. Or not quite kidding.&lt;/p&gt;

&lt;p&gt;Anyway, the TypeScript compiler is written in TypeScript (as expected). Less expected is that it'll soon be completely rewritten in Go. This raises two major problems:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Total dependence on a third-party framework is a problem in itself. If the switch to Go caught us off guard, we would have to urgently rewrite the entire codebase in another language or stay on a legacy platform. Not to mention that over &lt;em&gt;decades&lt;/em&gt;, open-source solutions may be abandoned.&lt;/li&gt;
&lt;li&gt;As already noted, we are a Java team. Our expertise centers around this language—we've been writing in it and analyzing it for years. Switching to a new development language would erase all that expertise.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The solution was obvious—split the analyzer architecture into two applications. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A wrapper over the TypeScript compiler that builds and passes the model.&lt;/li&gt;
&lt;li&gt;A Java-based analyzer requests first the AST from the wrapper and then semantic information when needed.&lt;/li&gt;
&lt;/ol&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%2Fgfhfdwhdkxk77e5dr40o.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%2Fgfhfdwhdkxk77e5dr40o.png" alt="1363_JavaScript_analyzer/image2.png" width="800" height="311"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, we wrap the model built by the TypeScript wrapper into protobuf and then pass it via gRPC. We've written two separate articles (&lt;a href="https://pvs-studio.com/en/blog/posts/java/1311/" rel="noopener noreferrer"&gt;first&lt;/a&gt;, &lt;a href="https://pvs-studio.com/en/blog/posts/java/1345/" rel="noopener noreferrer"&gt;second&lt;/a&gt;) about the intricacies of this process. Here are the key points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When passing the model, we translate the original representation into our own.&lt;/li&gt;
&lt;li&gt;We also perform normalization—simplifying the tree—to make the analysis simpler. For example, we ensure that &lt;code&gt;if&lt;/code&gt;branches always have braces, even if the language makes them optional.&lt;/li&gt;
&lt;li&gt;We automate the translation from a protobuf-serialized model using code generation—this makes it easy to react to changes and support new language versions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With this approach, we managed to mitigate the drawbacks mentioned: most development happens in Java, and we can replace the current wrapper for the TypeScript compiler with any other. We'll have to do this when TypeScript 7 is released, at which point we'll rewrite our wrapper in Go to match the compiler.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common abstract tree
&lt;/h2&gt;

&lt;p&gt;Traditionally, we have built code analyzers by taking a framework in the analyzed language for that same language, and then building the analyzer infrastructure around it.&lt;/p&gt;

&lt;p&gt;We used to reuse frameworks mainly for to the surrounding ecosystem—&lt;a href="https://pvs-studio.com/en/docs/manual/0038/" rel="noopener noreferrer"&gt;plog-converter&lt;/a&gt; and similar tools. Although in some cases we also borrowed analysis technologies, such as data-flow analysis from C++ into our own Java analyzer. The traditional approach had advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It's quite fast: creating a proof of concept takes days if not hours.&lt;/li&gt;
&lt;li&gt;When a developer writes an analyzer in the same language it targets, it improves both the analyzer quality and the developer's language knowledge.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But it also had disadvantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We would need people proficient in many different languages.&lt;/li&gt;
&lt;li&gt;Duplicated functionality must be reimplemented multiple times.&lt;/li&gt;
&lt;li&gt;Supporting new languages starts almost from scratch each time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And that last point turned out to be decisive for us. Besides JavaScript/TypeScript and Go, there will be support for other languages? What? Yes! &lt;a href="https://pvs-studio.com/en/subscribe/" rel="noopener noreferrer"&gt;Stay tuned&lt;/a&gt; for updates :)&lt;/p&gt;

&lt;p&gt;At this point, a thought occurred to us: why not build a common infrastructure for all languages? Well, most programming languages share many things: variables, control structures, operators, and so on. With a generalized language model, we wouldn't need to duplicate diagnostic rules, and with a common core, we wouldn't need to duplicate all the rest of the infrastructure.&lt;/p&gt;

&lt;h3&gt;
  
  
  CAT
&lt;/h3&gt;

&lt;p&gt;The idea of a generalized tree is not revolutionary. It's usually called UAST, and JetBrains, for example, &lt;a href="https://plugins.jetbrains.com/docs/intellij/uast.html" rel="noopener noreferrer"&gt;uses&lt;/a&gt; it for their IDEs. We liked the acronym CAT so much that we named our tree after it: Common Abstract Tree.&lt;/p&gt;

&lt;p&gt;The idea is simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We don't abandon the AST for a specific language. We still need it if we don't want to lose language-specific details.&lt;/li&gt;
&lt;li&gt;However, all nodes of a specific AST inherit common interfaces defined in CAT. If a diagnostic rule doesn't need language specifics, it can work only with these interfaces.&lt;/li&gt;
&lt;li&gt;Since we don't want to compromise the analysis accuracy, and language nuances are often necessary, the diagnostic rules allow for extending the general rules with language-specific refinements.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I think we'll release more detailed material on this topic in the future, but for now we'll stick to general principles. We can illustrate the approach with a simplified analog of &lt;a href="https://pvs-studio.com/en/docs/warnings/v6001/" rel="noopener noreferrer"&gt;V6001&lt;/a&gt;, which detects identical operands in a binary operation—errors like &lt;code&gt;a == a&lt;/code&gt;. Obviously, such a construct is valid in almost any language. It breaks down into typical language "building blocks":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The whole expression is called the same— an "expression".&lt;/li&gt;
&lt;li&gt;The comparison operation here is a "binary operation" of "equals" type.&lt;/li&gt;
&lt;li&gt;The left and right sides are also "expressions", which in our case have the narrower "identifier" type.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can roughly understand what we're looking at, but it's not obvious what to do next. So next, let's look at error detection on the tree.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a diagnostic rule?
&lt;/h3&gt;

&lt;p&gt;This is how diagnostic rules work.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A tree walker scans the AST of a specific language, stopping at each code element and running checks on them.&lt;/li&gt;
&lt;li&gt;For optimization, checks have preliminary filtering based on the type of code element they should trigger on.&lt;/li&gt;
&lt;li&gt;If a diagnostic rule finds a suspicious pattern, it issues a warning on that code fragment.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's get back to the error above. To find this error, we define a rule. It will check the binary expression's type (multiplication, for instance, is not of interest). It will also check that the left and right operands share the same type, and that these operands are the same. Handling chains of binary operands like &lt;code&gt;a == 0 &amp;amp;&amp;amp; b == 0 &amp;amp;&amp;amp; c == 0&lt;/code&gt; is less trivial, but the idea is roughly the same.&lt;/p&gt;

&lt;p&gt;This pattern can find the error in any language, but that doesn't mean languages can't have their own specifics. In JavaScript, there is a &lt;code&gt;foo &amp;amp;&amp;amp; foo.bar &amp;amp;&amp;amp; foo&lt;/code&gt; pattern. It appears in &lt;code&gt;return&lt;/code&gt; statements where we return a variable value from a condition after a preliminary check.&lt;/p&gt;

&lt;p&gt;For such cases, we provide several extension points for a general diagnostic rule: before it triggers; filtering intermediate results; and after the rule triggers. In our case, after the rule triggers on identical variable identifiers, we can check whether one of them is the last in the condition, thus eliminating false positives.&lt;/p&gt;

&lt;p&gt;And the normal mode of operation—where we write language-specific diagnostics is still available. Given our strong focus on finding typos in code, we needed to keep that flexibility.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Dr. Frankenstein assembled the analyzer from parts
&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%2Fg8xe7uarqkc462pw6zm4.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%2Fg8xe7uarqkc462pw6zm4.png" alt="1363_JavaScript_analyzer/image3.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we took an unconventional path, our architecture turned out to be noticeably more complex than usual:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;At the root, we have an ordinary CLI application written in Java.&lt;/li&gt;
&lt;li&gt;The core contains the CAT model and rules for it.&lt;/li&gt;
&lt;li&gt;For JavaScript/TypeScript, we have separate modules containing the specific language model and rule refinements.&lt;/li&gt;
&lt;li&gt;We can substitute the JavaScript/TypeScript module with a module for another language, reusing the generalized core during the analysis.&lt;/li&gt;
&lt;li&gt;The core and language layers also share the surrounding infrastructure, such as report generation.&lt;/li&gt;
&lt;li&gt;An indispensable part of the new analyzer is the TypeScript server, which uses the compiler API to build the program model and provide us with the AST and semantics.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can represent it simply like this:&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%2Fg47rghg5azhlljhd3uqy.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%2Fg47rghg5azhlljhd3uqy.png" alt="1363_JavaScript_analyzer/image4.png" width="800" height="618"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Despite the increased complexity of the system, from the first tests it performed well. &lt;/p&gt;

&lt;p&gt;The innovations didn't stop there. We also use compilation to a &lt;a href="https://www.graalvm.org/latest/reference-manual/native-image/" rel="noopener noreferrer"&gt;native image via GraalVM&lt;/a&gt;, which enabled us to switch to the latest Java versions. Also, we use DI based on &lt;a href="https://micronaut.io/" rel="noopener noreferrer"&gt;Micronaut&lt;/a&gt;, and overall, we try to keep up with new industry trends. &lt;/p&gt;

&lt;p&gt;By the way, this story is amusingly ironic. We have no continuity with the previous Java team that created Java analyzer—we didn't overlap in time. However, a spiritual continuity seems to &lt;a href="https://pvs-studio.com/en/blog/posts/java/0572/" rel="noopener noreferrer"&gt;exist&lt;/a&gt;. We independently came to a similar decision: not to follow the beaten path, but to explore new ways of creating analyzers and try to reuse existing work. Only they integrated data-flow analysis for C++ into Java, while we attempted to build a unified platform for analyzing different programming languages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Plugins
&lt;/h2&gt;

&lt;p&gt;To make it as easy as possible to integrate the static analyzer into the development process, we are developing plugins for the tools developers use. During the EAP, we provide a WebStorm plugin to run the analyzer from the IDE.&lt;/p&gt;

&lt;p&gt;At this stage, the plugin allows you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;run analysis on the whole project;&lt;/li&gt;
&lt;li&gt;filter the issued warnings;&lt;/li&gt;
&lt;li&gt;navigate through the code, viewing the code that triggered the warning;&lt;/li&gt;
&lt;li&gt;view the most interesting warnings using the Best Warnings feature;&lt;/li&gt;
&lt;li&gt;mark false positives.&lt;/li&gt;
&lt;/ul&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%2F3rji0xf9rxkkt5x43aw9.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%2F3rji0xf9rxkkt5x43aw9.png" alt="1363_JavaScript_analyzer/image5.png" width="800" height="671"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Later, when the MVP is ready, you'll be able to run the JS/TS static analyzer using &lt;a href="https://pvs-studio.com/en/docs/manual/6646/" rel="noopener noreferrer"&gt;our Visual Studio Code extension&lt;/a&gt;. At the same time, the WebStorm plugin will gain more extensive functionality.&lt;/p&gt;

&lt;p&gt;If you don't use WebStorm for development, you can still use the analyzer core via the CLI. You'll also be able to view reports—for example, in our PVS-Studio Atlas tool or in a browser. &lt;/p&gt;

&lt;h2&gt;
  
  
  Our testing system
&lt;/h2&gt;

&lt;p&gt;For testing JS/TS analyzer, we reused our special tool called &lt;strong&gt;Self-Tester&lt;/strong&gt;. It works with a base of open-source projects, performing regression testing of the analyzer. Here are the steps we follow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;download a specific version of the checked project from a GitHub repository;&lt;/li&gt;
&lt;li&gt;build the project;&lt;/li&gt;
&lt;li&gt;run the static analyzer via the CLI;&lt;/li&gt;
&lt;li&gt;compare the generated report with a reference report for that project.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach ensures that useful warnings won't disappear as a result of changes to the analyzer's code.&lt;/p&gt;

&lt;p&gt;Currently, the list of projects for the JavaScript Self-Tester is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/eslint/eslint" rel="noopener noreferrer"&gt;eslint&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/WordPress/gutenberg" rel="noopener noreferrer"&gt;gutenberg&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/bigskysoftware/htmx" rel="noopener noreferrer"&gt;htmx&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/jquery/jquery" rel="noopener noreferrer"&gt;jquery&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/overleaf/overleaf" rel="noopener noreferrer"&gt;overleaf&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/mozilla/pdf.js" rel="noopener noreferrer"&gt;pdf.js&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/prettier/prettier" rel="noopener noreferrer"&gt;prettier&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/facebook/react" rel="noopener noreferrer"&gt;react&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/mrdoob/three.js" rel="noopener noreferrer"&gt;three.js&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/webpack/webpack" rel="noopener noreferrer"&gt;webpack&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As for TypeScript analyzer, we're still working on the list of projects.&lt;/p&gt;

&lt;p&gt;Here's an &lt;a href="https://pvs-studio.com/en/blog/posts/java/0752/" rel="noopener noreferrer"&gt;article&lt;/a&gt; where we describe in detail how we develop and test diagnostic rules. Overall, nothing has changed for the JS/TS analyzer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Examples of errors
&lt;/h2&gt;

&lt;p&gt;Well, what story about a new static analyzer would be complete without demonstrating what it can find?  Next, we'll show you what the static analyzer found in our Self-Tester base and in various open-source projects.&lt;/p&gt;

&lt;p&gt;TypeScript analyzer will be available later than the JavaScript one during the EAP, but we were able to test it ahead of time. Just don't tell anyone :) &lt;/p&gt;

&lt;p&gt;So next, we'll look at errors in both JavaScript and TypeScript code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Findings in ESLint
&lt;/h3&gt;

&lt;p&gt;The first error comes from the JavaScript linter &lt;a href="https://github.com/eslint/eslint" rel="noopener noreferrer"&gt;ESLint&lt;/a&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;function&lt;/span&gt; &lt;span class="nf"&gt;isFirstBangInBangBangExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&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="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s"&gt;"UnaryExpression"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;operator&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s"&gt;"!"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argument&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s"&gt;"UnaryExpression"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;operator&lt;/span&gt; &lt;span class="o"&gt;===&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;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v7001/" rel="noopener noreferrer"&gt;V7001&lt;/a&gt; The operands of the '&amp;amp;&amp;amp;' operator are equivalent. &lt;a href="https://github.com/eslint/eslint/blob/811f4930f82ee2b6ac8eae75cade9bed63de0781/lib/rules/space-unary-ops.js#L109" rel="noopener noreferrer"&gt;space-unary-ops.js 109&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The analyzer reports identical operands of the binary "AND" expression.&lt;/p&gt;

&lt;p&gt;At first glance, it might seem like just an extra check, nothing critical. The method name and its JSDoc clarify the situation:&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;/**
* Check if the node is the first "!" in a "!!" convert to Boolean expression
* @param {ASTnode} node AST node
* @returns {boolean} Whether or not the node is first "!" in "!!"
*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This method checks whether the expression is a unary &lt;code&gt;!&lt;/code&gt; operator that contains another unary &lt;code&gt;!&lt;/code&gt; operator. Such a construction of unary operators in JavaScript casts the expression to a &lt;code&gt;Boolean&lt;/code&gt; type. &lt;/p&gt;

&lt;p&gt;So, what goes wrong here? The expression &lt;code&gt;!!1&lt;/code&gt; at the AST level looks 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;UnaryExpression&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="err"&gt;└──&lt;/span&gt; &lt;span class="n"&gt;argument&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UnaryExpression&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="err"&gt;└──&lt;/span&gt; &lt;span class="n"&gt;argument&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;value&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code snippet above, instead of checking the outer unary expression's operator, we check only the inner unary expression's operator &lt;code&gt;!&lt;/code&gt;  &lt;strong&gt;twice&lt;/strong&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Findings in Visual Studio Code
&lt;/h3&gt;

&lt;p&gt;Let's move to our dear &lt;a href="https://github.com/microsoft/vscode" rel="noopener noreferrer"&gt;Visual Studio Code&lt;/a&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;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_dispooables&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&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="n"&gt;_fileService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;onDidChangeFileSystemProviderRegistrations&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;_fileService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;onDidChangeFileSystemProviderCapabilities&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;=&amp;gt;&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;oldIgnorePathCasingValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;schemeIgnoresPathCasingCache&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;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scheme&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;oldIgnorePathCasingValue&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="n"&gt;undefined&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="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;schemeIgnoresPathCasingCache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&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;scheme&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;newIgnorePathCasingValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ignorePathCasing&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;from&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;newIgnorePathCasingValue&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="n"&gt;newIgnorePathCasingValue&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="p"&gt;;&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="k"&gt;const&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;entry&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;of&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;_canonicalUris&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;entries&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;entry&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;scheme&lt;/span&gt; &lt;span class="o"&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;scheme&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;continue&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;_canonicalUris&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&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="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 fragment is quite large, and it's hard to spot the error without hints. You can try to find it yourself if you'd like.&lt;/p&gt;

&lt;p&gt;What does the analyzer say? The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v7001/" rel="noopener noreferrer"&gt;V7001&lt;/a&gt; The operands of the '===' operator are equivalent. &lt;a href="https://github.com/microsoft/vscode/blob/main/src/vs/platform/uriIdentity/common/uriIdentityService.ts#L63" rel="noopener noreferrer"&gt;uriIdentityService.ts 63&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To make it clearer, here's the exact snippet with a bug:&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;const&lt;/span&gt; &lt;span class="n"&gt;oldIgnorePathCasingValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;schemeIgnoresPathCasingCache&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;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scheme&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;oldIgnorePathCasingValue&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="n"&gt;undefined&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="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;schemeIgnoresPathCasingCache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&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;scheme&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;newIgnorePathCasingValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ignorePathCasing&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;from&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;newIgnorePathCasingValue&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="n"&gt;newIgnorePathCasingValue&lt;/span&gt;&lt;span class="p"&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="k"&gt;return&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 the conditional statement, the same constant is compared with itself.&lt;/p&gt;

&lt;p&gt;This may be the result of a failed refactoring. The changes appeared in &lt;a href="https://github.com/microsoft/vscode/commit/781f31906ffff2447c8c3e77a49f7526f7f59a54#diff-e3e08baa4e6f82efaf0799a1ffb79b9238d51c6e0da031b257e2a13e205db28d" rel="noopener noreferrer"&gt;this commit&lt;/a&gt;. There, similar code was part of the &lt;code&gt;_handleFileSystemProviderChangeEvent&lt;/code&gt; method and looked 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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;currentCasing&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="n"&gt;undefined&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="p"&gt;;&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;newCasing&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;_calculateIgnorePathCasing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scheme&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;currentCasing&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="n"&gt;newCasing&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="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 erroneous fragment and this one are similar, only the naming differs. And the old snippet didn't have this error: it compared different constants.&lt;/p&gt;

&lt;p&gt;That's not the only thing the analyzer found. Look at another code snippet:&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="nf"&gt;renderQuotaItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;HTMLElement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;label&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;quota&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IQuotaSnapshot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;overageEnabled&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;boolean&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;:&lt;/span&gt; &lt;span class="kt"&gt;void&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;quotaItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DOM&lt;/span&gt;&lt;span class="p"&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;container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="err"&gt;'&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;quotaItemHeader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DOM&lt;/span&gt;&lt;span class="p"&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;quotaItem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="err"&gt;'&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;quotaItemLabel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DOM&lt;/span&gt;&lt;span class="p"&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;quotaItemHeader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="n"&gt;quotaItemLabel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;label&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;quotaItemValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DOM&lt;/span&gt;&lt;span class="p"&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;quotaItemHeader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="err"&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;quota&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unlimited&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;quotaItemValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;localize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;included&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;Included&lt;/span&gt;&lt;span class="err"&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="n"&gt;quotaItemValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;localize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;included&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;Included&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;// Progress bar - using same structure as chat status&lt;/span&gt;
  &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;progressBarContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DOM&lt;/span&gt;&lt;span class="p"&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;quotaItem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;bar&lt;/span&gt;&lt;span class="err"&gt;'&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;progressBar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DOM&lt;/span&gt;&lt;span class="p"&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;progressBarContainer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;bit&lt;/span&gt;&lt;span class="err"&gt;'&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;percentageUsed&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;getQuotaPercentageUsed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;progressBar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;percentageUsed&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;percentageUsed&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;90&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;overageEnabled&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;quotaItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="err"&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="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;percentageUsed&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;75&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;overageEnabled&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;quotaItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;warning&lt;/span&gt;&lt;span class="err"&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;As with the previous fragment, I suggest you find the error yourself first.&lt;/p&gt;

&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v7004/" rel="noopener noreferrer"&gt;V7004&lt;/a&gt; The 'then' statement is equivalent to the 'else' statement. &lt;a href="https://github.com/microsoft/vscode/blob/576cc0a5e1960ad40c8c88425e9271c79a085e05/src/vs/workbench/contrib/chat/browser/chatManagement/chatUsageWidget.ts#L102" rel="noopener noreferrer"&gt;chatUsageWidget.ts 102&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It refers to the following 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="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unlimited&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;quotaItemValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;localize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;included&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;Included&lt;/span&gt;&lt;span class="err"&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="n"&gt;quotaItemValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;localize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;included&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;Included&lt;/span&gt;&lt;span class="err"&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both then and else branches are identical, so the check doesn't make sense. Only the project authors know what was intended here. &lt;/p&gt;

&lt;p&gt;And we're moving on. Finally, let's look at two interesting spots in VS Code.&lt;/p&gt;

&lt;p&gt;Here's the first 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="k"&gt;for&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;namedImport&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;namedImports&lt;/span&gt;&lt;span class="p"&gt;)&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;isTarget&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
    &lt;span class="n"&gt;namedImport&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;getText&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="n"&gt;functionName&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;namedImport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;propertyName&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
        &lt;span class="n"&gt;namedImport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;propertyName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getText&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="n"&gt;functionName&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="n"&gt;isTarget&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&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;searchName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;namedImport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;propertyName&lt;/span&gt; 
                        &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;namedImport&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;namedImport&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;const&lt;/span&gt; &lt;span class="n"&gt;refs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getReferencesAtPosition&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="n"&gt;searchName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pos&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="o"&gt;??&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="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;refs&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;ref&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isWriteAccess&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&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;calls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;collect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;sourceFile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;isCallExpressionWithinTextSpanCollectStep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;textSpan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&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;lastCall&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calls&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;calls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&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;as&lt;/span&gt; &lt;span class="n"&gt;ts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CallExpression&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;undefined&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;lastCall&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;localizeCallExpressions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lastCall&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/v7012/" rel="noopener noreferrer"&gt;V7012&lt;/a&gt; The conditional expression always returns the same value. &lt;a href="https://github.com/microsoft/vscode/blob/13956d46e519a5e3ab9cccf0461c9df5b5e5fd24/build/lib/nls-analysis.ts#L186" rel="noopener noreferrer"&gt;nls-analysis.ts 186&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It refers to this 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="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;searchName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;namedImport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;propertyName&lt;/span&gt; 
                      &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;namedImport&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;namedImport&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Regardless of the condition, &lt;code&gt;searchName&lt;/code&gt; will be equal to &lt;code&gt;namedImport.name&lt;/code&gt;. This fragment should probably 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="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;searchName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;namedImport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;propertyName&lt;/span&gt; 
                      &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;namedImport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;propertyName&lt;/span&gt; 
                      &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;namedImport&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the second spot — similar, but in a different place:&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;const&lt;/span&gt; &lt;span class="n"&gt;passiveStyles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;borderColor:&lt;/span&gt; &lt;span class="n"&gt;hcBorderColor&lt;/span&gt; 
                    &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;hcBorderColor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
                    &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;observeColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                        &lt;span class="n"&gt;editorHoverForeground&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;_themeService&lt;/span&gt;
                    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;map&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="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transparent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
                     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nl"&gt;backgroundColor:&lt;/span&gt; &lt;span class="n"&gt;getEditorBackgroundColor&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;_viewData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;editorType&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nl"&gt;color:&lt;/span&gt; &lt;span class="err"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;opacity:&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="err"&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;const&lt;/span&gt; &lt;span class="n"&gt;editorBackground&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getEditorBackgroundColor&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;_viewData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;editorType&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;primaryActionStyles&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="k"&gt;this&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;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;alternativeActionActive&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&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="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;primaryActiveStyles&lt;/span&gt; 
        &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;primaryActiveStyles&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;secondaryActionStyles&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="k"&gt;this&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;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;alternativeActionActive&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&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="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;secondaryActiveStyles&lt;/span&gt; 
        &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;passiveStyles&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// TODO@benibenj clicking the arrow does not accept suggestion anymore&lt;/span&gt;
&lt;span class="k"&gt;return&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/v7012/" rel="noopener noreferrer"&gt;V7012&lt;/a&gt; The conditional expression always returns the same value. &lt;a href="https://github.com/microsoft/vscode/blob/576cc0a5e1960ad40c8c88425e9271c79a085e05/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsWordReplacementView.ts#L222" rel="noopener noreferrer"&gt;inlineEditsWordReplacementView.ts 222&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here it refers to this 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="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;primaryActionStyles&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="k"&gt;this&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;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;alternativeActionActive&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&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="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;primaryActiveStyles&lt;/span&gt; 
        &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;primaryActiveStyles&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we dug into the source code, we got the impression that this is the result of a failed refactoring. The following &lt;a href="https://github.com/microsoft/vscode/commit/0e4c00ab6aae9af2543215d167ff8dad46ab15e4#diff-0679a044e5a22245e5f544ec9de5a6e11b55f9d797dc9c0d6741952adb359b2eR136" rel="noopener noreferrer"&gt;commit&lt;/a&gt; introduced many changes, and these lines are among them. Before the fix, this snippet looked 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="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;primaryActionStyles&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="k"&gt;this&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;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;alternativeActionActive&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&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="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;passiveStyles&lt;/span&gt; 
        &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;activeStyles&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;secondaryActionStyles&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="k"&gt;this&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;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;alternativeActionActive&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&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="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;activeStyles&lt;/span&gt; 
        &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;passiveStyles&lt;/span&gt; 
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, in the first ternary operator, then and else expressions are identical.&lt;/p&gt;

&lt;h3&gt;
  
  
  Findings in Overleaf
&lt;/h3&gt;

&lt;p&gt;Let's move to the &lt;a href="https://github.com/overleaf/overleaf" rel="noopener noreferrer"&gt;Overleaf&lt;/a&gt; project.&lt;/p&gt;

&lt;p&gt;Remember earlier we touched upon the &lt;code&gt;replace&lt;/code&gt; methods annotation? That wasn't for nothing. Look at the following code snippet:&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;/**
 * Sanitize a translation string to prevent injection attacks
 *
 * @param {string} input
 * @returns {string}
 */&lt;/span&gt;
&lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sanitize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Block Angular XSS&lt;/span&gt;
  &lt;span class="c1"&gt;// Ticket: https://github.com/overleaf/issues/issues/4478&lt;/span&gt;
  &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;'''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;// Use left quote where (likely) appropriate.&lt;/span&gt;
  &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;' '&lt;/span&gt;&lt;span class="err"&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="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/v7010/" rel="noopener noreferrer"&gt;V7010&lt;/a&gt;. The return value of function 'replace' is required to be utilized. &lt;a href="https://github.com/overleaf/overleaf/blob/1b70f09bee2f9fbc61ba08ca4970f172d7dd0d30/services/web/scripts/translations/sanitize.js#L14" rel="noopener noreferrer"&gt;sanitize.js 14&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you look at the line highlighted by the analyzer, it becomes clear that there's a typo: the changed value of &lt;code&gt;replace&lt;/code&gt; in the second line of the method remains unused.&lt;/p&gt;

&lt;p&gt;At first, this error seemed critical to us, as the comments and JSDoc show that this method sanitizes external data. But then it became clear that the line pointed out by the analyzer is only a cosmetic change. This &lt;code&gt;replace&lt;/code&gt; formats quotes, replacing closing quotes at the beginning of a phrase with opening ones. Still, if the error had occurred one line earlier, the consequences would have been more severe.&lt;/p&gt;

&lt;p&gt;The analyzer found another error in this project:&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="n"&gt;change&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isIntersecting&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;videoIsVisible&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;true&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;videoEl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;readyState&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;videoEl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HAVE_FUTURE_DATA&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="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;videoEl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ended&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;videoEl&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
          &lt;span class="n"&gt;debugConsole&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="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;Video&lt;/span&gt; &lt;span class="n"&gt;autoplay&lt;/span&gt; &lt;span class="n"&gt;failed&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="err"&gt;'&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="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;videoEl&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
          &lt;span class="n"&gt;debugConsole&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="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;Video&lt;/span&gt; &lt;span class="n"&gt;autoplay&lt;/span&gt; &lt;span class="n"&gt;failed&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="err"&gt;'&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="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/v7004/" rel="noopener noreferrer"&gt;V7004&lt;/a&gt;. The 'then' statement is equivalent to the 'else' statement. &lt;a href="https://github.com/overleaf/overleaf/blob/1b70f09bee2f9fbc61ba08ca4970f172d7dd0d30/services/web/frontend/js/features/autoplay-video/index.js#L39" rel="noopener noreferrer"&gt;index.js 39&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here, the behavior in both then and else branches is identical. This is likely due to code copying, and the behavior in one of the branches should differ. &lt;/p&gt;

&lt;p&gt;In a &lt;a href="https://github.com/overleaf/overleaf/blob/ec5a283e9ed160c587f452c742314f1f4f3c5645/services/web/frontend/js/features/autoplay-video/index.js#L63" rel="noopener noreferrer"&gt;subsequent commit&lt;/a&gt; that touched this file, the behavior was changed, and the issue disappeared.&lt;/p&gt;

&lt;h3&gt;
  
  
  Finding in Prisma
&lt;/h3&gt;

&lt;p&gt;The next project is &lt;a href="https://github.com/prisma/prisma" rel="noopener noreferrer"&gt;Prisma&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;The error appeared in the following 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;export&lt;/span&gt; &lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="n"&gt;strongGreen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str&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="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="k"&gt;return&lt;/span&gt; &lt;span class="err"&gt;`\&lt;/span&gt;&lt;span class="n"&gt;u001b&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="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="mi"&gt;48&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;u001b&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="n"&gt;strongRed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str&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="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="k"&gt;return&lt;/span&gt; &lt;span class="err"&gt;`\&lt;/span&gt;&lt;span class="n"&gt;u001b&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="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="mi"&gt;48&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="mi"&gt;52&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;u001b&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="n"&gt;strongBlue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str&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="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="k"&gt;return&lt;/span&gt; &lt;span class="err"&gt;`\&lt;/span&gt;&lt;span class="n"&gt;u001b&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="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="mi"&gt;48&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="mi"&gt;52&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;u001b&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="err"&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/v7002/" rel="noopener noreferrer"&gt;V7002&lt;/a&gt; The body of a function is fully equivalent to the body of another function. &lt;a href="https://github.com/prisma/prisma/blob/ecae3b65bbed748445c6230de583c51bb921e7df/packages/migrate/src/utils/customColors.ts#L5" rel="noopener noreferrer"&gt;customColors.ts 5&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The analyzer reports that the bodies of the &lt;code&gt;strongRed&lt;/code&gt; and &lt;code&gt;strongBlue&lt;/code&gt; functions are identical. What's going on inside them? &lt;/p&gt;

&lt;p&gt;These functions return specially formatted strings to display styled text in various terminals. They are called ANSI escape sequences. If you've never heard of them, let's see how it works using the return value of &lt;code&gt;strongRed&lt;/code&gt; as an example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;\u001b[&lt;/code&gt; is a command that the terminal interprets as a special signal: "a text formatting command is coming".&lt;/p&gt;

&lt;p&gt;Then comes the string &lt;code&gt;[1;31;48;5;52m&lt;/code&gt;. These are text display settings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;1&lt;/code&gt; makes the text bold;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;31&lt;/code&gt; makes the text red;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;48&lt;/code&gt; indicates that the following settings will control the background color;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;5;52&lt;/code&gt; sets the background to a color from the 255-color RGB palette, corresponding to index 52;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;m&lt;/code&gt; applies these styles to the text;&lt;/li&gt;
&lt;li&gt;${str}&lt;code&gt;is the text to which all these styles apply;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;\u001b[m&lt;/code&gt; is a command that resets all previously applied styles for the subsequent text.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's get back to the error. Both the &lt;code&gt;strongRed&lt;/code&gt; and &lt;code&gt;strongBlue&lt;/code&gt; functions return the same red text color (31) and the same background color (52). &lt;/p&gt;

&lt;p&gt;For &lt;code&gt;strongBlue&lt;/code&gt;, the text color obviously should be blue (index 34), and the authors should also consider the background color.&lt;/p&gt;

&lt;p&gt;If you're interested, you can read &lt;a href="https://en.wikipedia.org/wiki/ANSI_escape_code" rel="noopener noreferrer"&gt;here&lt;/a&gt; more about what ANSI escape sequences are and how they work. &lt;/p&gt;

&lt;h3&gt;
  
  
  Findings in React
&lt;/h3&gt;

&lt;p&gt;Our demonstration continues with the well-known &lt;a href="https://github.com/facebook/react" rel="noopener noreferrer"&gt;React&lt;/a&gt; project.&lt;/p&gt;

&lt;p&gt;Here's the 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;for&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;property&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;properties&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;property&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;kind&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;ObjectProperty&lt;/span&gt;&lt;span class="err"&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;effects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="nl"&gt;kind:&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;Capture&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;from:&lt;/span&gt; &lt;span class="n"&gt;property&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;place&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;into:&lt;/span&gt; &lt;span class="n"&gt;lvalue&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;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;effects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="nl"&gt;kind:&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;Capture&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;from:&lt;/span&gt; &lt;span class="n"&gt;property&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;place&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;into:&lt;/span&gt; &lt;span class="n"&gt;lvalue&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/v7004/" rel="noopener noreferrer"&gt;V7004&lt;/a&gt;. The 'then' statement is equivalent to the 'else' statement. &lt;a href="https://github.com/facebook/react/blob/3cb2c42/compiler/packages/babel-plugin-react-compiler/src/Inference/InferMutationAliasingEffects.ts#L1771" rel="noopener noreferrer"&gt;InferMutationAliasingEffects.ts 1771&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The same warning we saw earlier, but now in TypeScript code. The expressions in then and else branches are identical. Either this is the result of a failed refactoring, which can be very misleading, or it's a real error.&lt;/p&gt;

&lt;h3&gt;
  
  
  Finding in jQuery
&lt;/h3&gt;

&lt;p&gt;Finally, a simple error from the &lt;a href="https://github.com/jquery/jquery" rel="noopener noreferrer"&gt;jQuery&lt;/a&gt; project:&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;fullscreenSupported&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exitFullscreen&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
  &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exitFullscreen&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
  &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;msExitFullscreen&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
  &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mozCancelFullScreen&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
  &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;webkitExitFullscreen&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/v7001/" rel="noopener noreferrer"&gt;V7001&lt;/a&gt; The operands of the '||' operator are equivalent. &lt;a href="https://github.com/jquery/jquery/blob/6cb507faf3b6b25f0f3b5870e40a615fc19af9b1/test/integration/data/gh-1764-fullscreen.js#L13" rel="noopener noreferrer"&gt;gh-1764-fullscreen.js 13&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here, &lt;code&gt;document.exitFullscreen&lt;/code&gt; appears twice in the condition. &lt;/p&gt;

&lt;p&gt;Such errors may indicate that, as a result of copying code, the condition contains the wrong value. In this case, it's likely just an extra check. Still, we need to be very careful with such fragments. &lt;/p&gt;

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

&lt;p&gt;We've shown you our big effort—the new PVS-Studio analyzer for JavaScript and TypeScript. But in reality, what we have now is only the tip of the iceberg. Although, as you may have noticed, it can already find errors.&lt;/p&gt;

&lt;p&gt;To make the analysis even more advanced, besides the AST and semantics, we still need to implement many more technologies inside the analyzer. There is a whole bottomless ocean of what an analyzer can do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/blog/terms/7004/" rel="noopener noreferrer"&gt;data-flow analysis&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/blog/posts/1048/#ID51D242EE71" rel="noopener noreferrer"&gt;function annotation&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/blog/terms/6785/" rel="noopener noreferrer"&gt;interprocedural context-sensitive analysis&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/blog/terms/6791/" rel="noopener noreferrer"&gt;intermodular analysis&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/blog/terms/7009/" rel="noopener noreferrer"&gt;alias analysis&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/blog/terms/6496/" rel="noopener noreferrer"&gt;taint analysis&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;and much, much more.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, we have plenty to do, and the work may never be truly finished. But the more we do, the better and deeper our analysis will become.&lt;/p&gt;

&lt;p&gt;However, we've made a great start: we've laid the foundation for JavaScript and TypeScript analyzers, a basic set of diagnostic rules, and a platform for implementing new analyzers. Besides refining the analyzer, we'll implement various integrations and generally improve the user experience.&lt;/p&gt;

&lt;p&gt;As part of the EAP, the analyzer for the Go language is also available. We've already posted several articles about the errors we found with it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/blog/posts/go/1342/" rel="noopener noreferrer"&gt;Go vet can't go: How PVS-Studio analyzes Go projects&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/blog/posts/go/1350/" rel="noopener noreferrer"&gt;Exponentiation != bitwise exclusive OR&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's another &lt;a href="https://pvs-studio.com/en/blog/posts/go/1329/" rel="noopener noreferrer"&gt;article&lt;/a&gt; similar to this one on how to implement your own analyzer for Go. &lt;/p&gt;

&lt;p&gt;If you want to try our new analyzers, you can try them &lt;a href="https://pvs-studio.com/en/pvs-studio-eap/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With that, we'll say goodbye. See you soon!&lt;/p&gt;

</description>
      <category>tooling</category>
      <category>javascript</category>
      <category>programming</category>
      <category>news</category>
    </item>
    <item>
      <title>New webinar session on how to make a programming language with lexer</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Wed, 15 Apr 2026 09:36:59 +0000</pubDate>
      <link>https://forem.com/pvsdev/new-webinar-session-on-how-to-make-a-programming-language-with-lexer-4onp</link>
      <guid>https://forem.com/pvsdev/new-webinar-session-on-how-to-make-a-programming-language-with-lexer-4onp</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;&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%2F1kos20bf3asffwmb60j1.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%2F1kos20bf3asffwmb60j1.png" alt=" " width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this session, we continue building our own programming language from the ground up. Previously, we covered how terminal symbols fit into a grammar. Now we move one layer deeper: &lt;strong&gt;the lexer.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The lexer is the part of the parsing pipeline that operates on terminal symbols. It takes a raw input stream and turns it into a sequence of tokens — classifying lexemes into meaningful units. This process, as you know, is called tokenization.&lt;/p&gt;

&lt;p&gt;We won't stop at theory. During the webinar, we'll walk through how a lexer is actually implemented in code.&lt;/p&gt;

&lt;p&gt;This session is aimed at developers who want to go beyond using languages and start understanding how they work under the hood.&lt;/p&gt;

&lt;p&gt;If you missed our previous webinar sessions, don't worry! You can familiarize with them on our YouTube channel or our website. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First talk&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=ylPuGE2itQY" rel="noopener noreferrer"&gt;Let's make a programming language. Intro on YouTube&lt;/a&gt;&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=web3" rel="noopener noreferrer"&gt;Let's make a programming language. Intro on the official PVS-Studio website&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Second talk&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=-yuU92URgz8" rel="noopener noreferrer"&gt;Let's make a programming language. Grammars on YouTube&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=web3" rel="noopener noreferrer"&gt;Let's make a programming language. Grammars on the official PVS-Studio website&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to get the videos earlier, all recordings will be sent to all registered participants after the webinar is finished.&lt;/p&gt;

&lt;p&gt;Don't miss the opportunity to create your own language with the experienced developer. &lt;/p&gt;

&lt;p&gt;It's going to be engaging and approachable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Join new webinar&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;&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;&lt;/p&gt;

&lt;p&gt;P.S. And don't forget your inbox to confirm the registration!&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>c</category>
      <category>development</category>
      <category>programming</category>
    </item>
    <item>
      <title>Changes to PVS-Studio's free licensing policy</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Fri, 10 Apr 2026 11:56:04 +0000</pubDate>
      <link>https://forem.com/pvsdev/changes-to-pvs-studios-free-licensing-policy-4i4i</link>
      <guid>https://forem.com/pvsdev/changes-to-pvs-studios-free-licensing-policy-4i4i</guid>
      <description>&lt;p&gt;We have updated licensing terms regarding the free use of our tool. Here is a breakdown of the changes.&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%2F0gr6fs6b4c9sq8rx6wy5.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%2F0gr6fs6b4c9sq8rx6wy5.png" alt="1362_Free_license_update/image1.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PVS-Studio static code analyzer offers multiple free licensing options. Let's discuss how they will change and what options are now available.&lt;/p&gt;

&lt;p&gt;Previously, you could use the analyzer for free by adding special comments to the source code and entering an activation key. Since April 2026, this licensing option is no longer available. If you have been using the analyzer this way, please obtain an activation key via &lt;a href="https://pvs-studio.com/en/blog/posts/0614/" rel="noopener noreferrer"&gt;one of the other ways&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The changes affect the free access to PVS-Studio for students and teachers. We have suspended the student licensing program while we update its terms and conditions. Our goal is to create a new academic licensing system that is convenient and easy for individual users and educational institutions to understand. &lt;/p&gt;

&lt;p&gt;We will notify you when academic licenses are available again. To make sure you don't miss the news, we recommend &lt;a href="https://pvs-studio.com/en/subscribe/" rel="noopener noreferrer"&gt;subscribing to our newsletter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Free licensing terms for open-source projects, public security experts, and Microsoft MVPs remain unchanged. You can learn more about them &lt;a href="https://pvs-studio.com/en/blog/posts/0614/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you would like to check your project using PVS-Studio static analyzer, you can &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=1362" rel="noopener noreferrer"&gt;get a trial license&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>news</category>
      <category>softwaredevelopment</category>
      <category>software</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Game++. Part 1.1: C++, game engines, and architectures</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Thu, 09 Apr 2026 11:57:46 +0000</pubDate>
      <link>https://forem.com/pvsdev/game-part-11-c-game-engines-and-architectures-bif</link>
      <guid>https://forem.com/pvsdev/game-part-11-c-game-engines-and-architectures-bif</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%2F1woankofqxi68f767uqu.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%2F1woankofqxi68f767uqu.png" alt="1361_pt_1/image1.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why C++?
&lt;/h2&gt;

&lt;p&gt;Despite its seemingly archaic nature and complexity, C++ remains the mainstream language for developing games and game engines. The reason lies in the unique balance between low-level control and high-level abstractions, which is critically game development.&lt;/p&gt;

&lt;p&gt;On the one hand, C++ provides full control over system resources. Developers can manage every memory byte, optimize processor cache usage, and build synchronization and parallel execution systems tailored for specific architectures. C++ allows developers to create code that efficiently runs on low-end PCs, past gen consoles, or mobile devices. It also makes it possible to manually manage memory and data placement to maximize cache efficiency, which is crucial for achieving high performance.&lt;/p&gt;

&lt;p&gt;On the other hand, modern C++ provides powerful high-level abstractions for building complex systems. Features such as classes, inheritance, templates, containers, smart pointers, RAII, and lambdas enable the development of large-scale architectures with modular logic, entity systems, and event-driven mechanisms. When used wisely—without excessive use of templates and metaprogramming—the code remains expressive and maintainable.&lt;/p&gt;

&lt;p&gt;Other high-level programming languages, such as Python, JavaScript, C#, and Java, offer undeniable advantages, including automatic memory management, convenient syntactic sugar, extensive standard libraries, and significantly improved readability. This is why they are popular among designers, technical artists, and UI programmers for scripting tasks in games. However, these languages ​​have serious drawbacks when it comes to developing game engines. Their reliance on virtual machines or managed runtime (JVM. CLR, etc), unpredictable garbage collector behavior that can block execution at the worst possible moment, lack of precise control over execution time, dependence on external solutions, and suboptimal memory layout schemes less suitable for performance-critical subsystems.&lt;/p&gt;

&lt;p&gt;Such limitations are unacceptable in the realm of game development, especially at the engine level. Garbage collectors, extra memory overhead from virtual machines, or inefficient use of the processor cache can cause random freezes and frame rate drops. Physics simulations, rendering systems, netcode, and core engine logic require predictable performance, maximum resource efficiency, and low tolerance for latency spikes and instability.&lt;/p&gt;

&lt;p&gt;C++ remains relevant in the gaming industry, not because it is the best option, but because the alternatives are too abstract to solve the real technical challenges of game systems. This is a conscious trade-off: the language is complex and potentially dangerous, but when used correctly, it offers the efficiency necessary for creating modern games. As long as performance and resource control requirements remain mission-critical, C++ will continue to be a key player in the game development industry.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a game engine?
&lt;/h2&gt;

&lt;p&gt;Back in the day, when game engines were simple, writing your own was a no-brainer because if you didn't have an engine, you basically didn't have a game. Some people would buy someone else's engine and enjoy the beauty of reinvented wheels, while others would spend months or even years creating their own.&lt;/p&gt;

&lt;p&gt;To understand how, and more importantly why, certain mechanisms are used within a game or engine to identify, locate, and eliminate performance and architecture issues, it's necessary to understand how game engines work and how they are created.&lt;/p&gt;

&lt;p&gt;John Carmack once said, "The right move is to build your own engine," though many would argue that it's not that simple. However, Doom's "father" is widely known for his contributions to game engine development. He also frequently criticized off-the-shelf engines in general, advocating for in-house technological solutions. His philosophy is consistent: having an in-house engine gives developers complete control over the technology and the power to create solutions tailored to their projects' specific needs.&lt;/p&gt;

&lt;p&gt;Well, everybody's got a point, and there's no single way to do things—it depends on the situation. Perhaps creating an engine isn't as difficult as it seems? But why bother doing it at all? What does it really mean to "create a game engine"?&lt;/p&gt;

&lt;p&gt;I've worked with various game engines and built a couple of my own from scratch, two of which ended up in the trash. Three proprietary games were released on my third one but saw little success, and that engine was sold to a studio for some sum 15 years ago. I've seen developers using other off-the-shelf engines, complaining about issues, and devising their own solutions. I've studied—and continue to do so—the source code of other engines, both open-source and proprietary.&lt;/p&gt;

&lt;p&gt;My experience may be somewhat biased, though: I've always wanted to create strategy games; however, most of the projects I've worked on have been shooters.&lt;/p&gt;

&lt;h2&gt;
  
  
  The first key question is: why do you want to do it?
&lt;/h2&gt;

&lt;p&gt;Deciding to create a game or a game engine may seem like either a crazy idea or a genius one. Well, it's actually both. This is one of the cases when the journey is way more exciting than its destination.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;...Firstly, secondly, and thirdly, it's a lot of fun, I promise!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Developing an engine is like playing with LEGO, but for adults and usually alone. You can add rendering, particle systems, and hot-reloading for scripts. You'll laugh, be amazed, and possibly even curse, but one thing's for sure: it won't be boring!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;...Fourthly, companies will pay good money for such professional experience.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The fact you went through all the trial and error means you've gained something you can't learn in any textbook—a hands-on understanding of how a game engine works under the hood. Real-world experience is the greatest asset in the job market, and game studios are willing to pay handsomely for an in-depth knowledge of how game technologies work. While most people know how to use off-the-shelf solutions, when an issue pops up at the engine level, they need someone who's been there and done that—someone who knows where to look for the root of the problem.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;...You'll definitely learn a lot along the way.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This will help you better understand not just engines, but other things as well. You'll develop real engineering intuition, grasp the concept of "heavy algorithms," learn why loading textures in a frame is a bad idea, and what are cache-friendly data structures designed to maximize the usage of processor cache memory.&lt;/p&gt;

&lt;p&gt;This kind of knowledge comes from personal experience, not books. When you eventually stop working on your engine—which you most likely will—you will approach game and software development differently.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;...By the way, speaking of a trash can...&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Based on experience, that's where your first engine will end up, and so will your second one. This is okay—it's just how learning works. You might've heard of the "three systems" rule: the first system is a trial run, the second tries to do everything "right," and the third one actually works. So, don't be afraid to code, get rid of bad ideas, and start over. Each "failed" attempt doesn't waste your time; it gives you invaluable experience that brings you closer to creating that third system that will actually work.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;...Your engine is as free as your spare time after work.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As it turns out, it's not free at all. These are hundreds of hours spent in the evenings and late at night. These are internal debates. These are refactorings of what you enthusiastically wrote two weeks ago. These are "nearly functional" prototypes, and while you may say, "I'll finish the UI later," what you gain in return is understanding and confidence in your decisions.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;...You can and should change everything to suit your wants and needs.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Want to hot-reload JavaScript configurations? Then you'll need to learn how JavaScript and its virtual machine work. Tired of the old way to load textures? Create your runtime atlas directly from disk files. The only real limits here are your skills and the amount of time you have. Bizarre ideas are good—they create unique solutions.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;...You have full control over all the inner workings.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;What systems are involved, how the world update works, and what data structure stores game objects. You won't have a "black box," only a call stack and an urge to streamline everything.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;...You can use your favorite programming language.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Like Rust? Use it! Prefer C++? Welcome to the pain club. Some people write game engines in Go. I've seen engines written in Lua, Python, Haskell, and even Erlang. I haven't seen one written in COBOL yet, but I bet it exists somewhere. What matters most is that you know why you picked the particular language.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;...You can keep the distribution tiny.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For example, the binary file for my pet project is about 2 MB. It contains scripts, settings, and even some assets. The rest loads from the disk. For a small game, this is a luxurious dream, especially compared to engines where even a "Hello World" script weighs 200 MB.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;...You can release your engine to the public.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And that's a great idea. Firstly, to see how others use it. Secondly, to find those who can actually compile it. Only a few will succeed—about 0.1% of those who downloaded the engine. They are the right people to bring into your team, though. By the way, Epic Games did something similar: active contributors to Unreal Engine were offered official jobs.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;...You can even sell it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Just be careful, because supporting an engine for other people's whims is a different kind of hell. They'll inevitably ask you to "make it just like in Unity, but different." This is an endless struggle.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;...You'll never be disappointed that the engine developers didn't implement the feature you want!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You're the developer here. Want a new navigation system? Implement it. Need to expand the save system? Go ahead. You won't get turned down with these bug report replies like, "Scheduled for Q5 next year."&lt;/p&gt;

&lt;p&gt;&lt;em&gt;...Finally, about tech interviews.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Having your own game engine almost always sparks an interesting conversation. Now, instead of just answering questions, you can confidently ask some of your own: "How do you update game objects? How does asset loading work?" At that point, people start listening. They realize they're talking to an engineer who has created their own solution and isn't afraid to discuss it—not just a programmer.&lt;/p&gt;

&lt;p&gt;For me, the first two points and the last one are the most important. Learning is fun, learning while creating a game is twice as fun. I also really enjoy programming, pushing the boundaries of what a language allows, and delving into the complex details and subtleties of algorithms and systems. Well, meaningful conversations during interviews are a nice bonus.&lt;/p&gt;

&lt;p&gt;Game developers always complain about engines, no matter how powerful and convenient they are: this doesn't work, that is broken, this new feature doesn't support that old one thing, and that old feature was requested ten years ago, but still nothing has been added. Of course, this is all for a reason—if you've ever worked for a big company, you'll totally get what I mean. However, blaming someone else is always easier than taking responsibility. If you need some new feature, why not just implement it yourself? Well, you can't, the engine doesn't belong to you. It's someone else's, but the disappointment is still yours. This is hardly surprising. Just as it's hardly surprising that the desired feature will be added to your engine when &lt;em&gt;you&lt;/em&gt; really need it.&lt;/p&gt;

&lt;p&gt;By the early 2000s, the term "game engine" had become part of developers' vocabulary. However, most projects were still custom-built, and almost all of the technology was written from scratch, including custom rendering engines, animation systems, and physics engines. It used to be common practice to build an engine tailored to a specific game's genre, platform, and technical limitations. The industry has changed significantly since then: games have evolved into commercially viable, mass-market products, and development technologies have become more standardized and modular. Modern game engines, such as Unreal Engine, Unity, CryEngine, and Source, as well as the proprietary tools of major studios, have evolved into comprehensive SDKs that empower developers to create entire game franchises across various genres on a unified technological foundation rather than just a single project.&lt;/p&gt;

&lt;p&gt;Although engine implementations can greatly vary, a relatively stable set of key subsystems had emerged by the mid-2000s: graphics, physics, animation, audio, AI, UI, system logic, replication and networking, in-game scripting, data systems, etc. Moreover, specific patterns and architectural approaches have begun to emerge within these components, recurring from project to project. These include ECS (Entity-Component System), behavior trees (BT), deferred rendering, and rollback-based concurrency control system. However, developers had to gather information on these topics piece by piece: an article here, a talk at GDC there, or a code snippet from GitHub.&lt;/p&gt;

&lt;p&gt;There were books on graphics, physics, and AI architecture, but those were just scattered bits of knowledge. Almost no resources tied everything together by explaining not only what these things are, but also how they work under the hood and how to design game architecture while balancing technical limitations and production realities, as they did at GEA.&lt;/p&gt;

&lt;h2&gt;
  
  
  The second key question is: do you really need it?
&lt;/h2&gt;

&lt;p&gt;Personal projects are always challenging and require crazy amounts of time. Of course, a lot depends on your end goals, but don't expect to build an Unreal Engine clone in a year. After all, it took a team of highly skilled engineers twenty years to develop the engine as we know it today, and the community has also contributed to its development. You'll always feel like something is missing in your own game engine. It takes many years of hard work to achieve even a fraction of capabilities and user-friendliness that mature tools offer.&lt;/p&gt;

&lt;p&gt;A custom-built game engine can rarely compete with major industry ones such as Unreal Engine, Unity, CryEngine, or Godot. A game engine can compete only if there's a large, well-funded studio behind it. However, this book is probably not for those folks, since they've likely already got their own tool or are using one of the ones listed above.&lt;/p&gt;

&lt;p&gt;Keep in mind that rarely pays off for small teams. There won't be a moment when it suddenly starts generating generous profit. No, it's unprofitable even for industry leaders. Games make money, not engines... According to Epic Games' report, the cost of developing Unreal Engine over the past four years alone exceeded $160 million. It's as if every year they release a new AAA game that we can't even play!&lt;/p&gt;

&lt;p&gt;In 99/100 cases, game engine developers never make it to the actual game if their goal is to develop the engine itself. This path leads straight to the game being canceled. Most people may consider someone who wastes time developing their own engine to be a silly person.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Advice&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you want to release your game as quickly as possible, just go with a ready-made engine and use the features it offers. If you want to grow as a developer and lay the foundation for future projects beyond game development—and if you have enough time, energy, and patience—then go for it! A custom-built game engine is probably the best way to apply your knowledge. Plus, once you've created a solid base, you can reuse it as much as you want, improving it with each new game.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Libraries + cmake != Engine
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Since you've read this far, I haven't convinced you to quit this thankless job. Well, let's move on then...&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Can we call SDL/SFML/Allegro game engines, considering that tons of indie games have been made using them? Definitely not—these are libraries for wrapping platform code, although they do enable many of the basic game engine features. What about Vulkan/DX12? Absolutely not—these are graphics APIs. And what about FMOD/WWISE?&lt;/p&gt;

&lt;p&gt;Again, no—however, they can be used to create a two- or three-dimensional scene, albeit an audio one. So, let's summarize:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Libraries + API != an engine either&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now, imagine a small project about exterminating spiders and building a base on another planet, which combines Allegro, DX11, and stb (a set of different header-only solutions for all kinds of situations) to draw moving sprites on the screen. You probably recognized Factorio from this description. It all started with the demo version on Allegro and just a few sprites:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Allegro + API + stb + talent == Factorio&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Is it a game engine? The answer is still no, but we're getting closer: a game engine doesn't exist without a game (or games) built on it. Until a game is released, it's just a set of libraries glued together using CMake. Can a game engine be just a combination of graphics, animation, and user input processing? So, the conclusion is as follows:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Factorio != the engine &amp;amp;&amp;amp; Factorio == the game&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A game engine without a game is just a collection of tools, libraries, and other components designed to help create games. A game without an engine is still a game. If you think that such a definition of an engine without a game is vague and almost useless, you're right.&lt;/p&gt;

&lt;p&gt;Do you really need complex material editors and miles of shaders, seamless geometry and global illumination for it, 3D physics with inverse kinematics, and network game support if you're making a 2D pixel-art platformer?&lt;/p&gt;

&lt;p&gt;Unreal Engine has all these features, and they work pretty well, but do you really need them all? They require experience, time to get used to, and knowledge of how to configure and use them. A simple platformer game must only handle input, render sprites, maybe even display raw &lt;code&gt;.png&lt;/code&gt; files on the screen, and play sound. You can learn all this in a couple of days from free tutorials on YouTube. You'll spend these evenings doing something useful, rather than struggling with the character controller in the editor. Finally, you've reached the main point of the whole endeavor—creating your game.&lt;/p&gt;

&lt;p&gt;But what if you'd want to create an AAA blockbuster with next-gen graphics, physics, and so on? Well, then you'd need all these complex systems. It would also take a few decades of free time, or a team of talented engineers working full-time exclusively on the engine, to bring it all to life. Yes, modern game engines have indeed moved hopelessly far away from retro platformers.&lt;/p&gt;

&lt;p&gt;Still, most game engines have an architecture that integrates all these subsystems into one framework. Not all of them—at least not yet—but it's important to understand that a game engine can contain only some of these features and still be considered a game engine. Not every game needs all these features at once; otherwise, no indie game would ever be released. You can design a small engine specifically for your game. But let's be honest—big game engine capabilities spoiled us, so we expect the same performance from everything else.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some useful stuff
&lt;/h2&gt;

&lt;p&gt;However, if the engine was designed specifically for a game, then having fewer features is perfectly acceptable. No matter how you develop games—whether on your own or someone else's engine, from scratch, or building on the ruins of a previous project—you'll start to notice recurring patterns. Everything that seemed like a "temporary solution" at first will eventually either become part of the foundation or be tossed in the trash. This is how the standard set of essential components emerges. First things first—when it comes to visual level and UI editors—no need to manually write levels, even if it's just a quick prototype in an evening.&lt;/p&gt;

&lt;p&gt;When you already have something moving on the screen, the next issue inevitably appears—updating the logic. A rather simple approach is to put everything in the update function (&lt;code&gt;Game::Update()&lt;/code&gt;), updating whatever reaches it in time. Then, you add the update priority, followed by the dependencies between systems, and then the question arises: if physics runs separately, what about the collision-based logic? Even if the game is small, it's better to design the logic as an independent system than as a series of "crutches" dependent on the array element order. Components work best if they know nothing about each other—they subscribe to events and don't care what invokes them.&lt;/p&gt;

&lt;p&gt;Next comes the universal issue of the scene/level system. It seems obvious: you have a menu, gameplay, and cutscenes. However, when a level loads within another level, then one game mode switches to another without exiting to the menu; when it's necessary to "freeze" a scene, overlay a tutorial, and then return back—that's when the scene system falls apart if it wasn't designed for these cases. A scene isn't just a list of objects; it's a managed container of logic, data, dependencies, and transitions.&lt;/p&gt;

&lt;p&gt;Speaking of objects, it's impossible to overlook the entity manager. Though it may seem useless and redundant at first, it proves to be the core of the entire architecture: It's responsible for creation, destruction, identification, tagging, access to components, and sometimes even debugging.&lt;/p&gt;

&lt;p&gt;By the way, when it comes to saving, there's a game state serialization system. Some people think the only reason to use it is to save the game, but it's actually essential for everything. Auto-saving, passing states between scenes, saving configurations, replays, and rollbacks—it's amazing how many problems disappear when you can "put everything in a box and restore it."&lt;/p&gt;

&lt;p&gt;And finally, the variable inspector. I'm not referring to a full-fledged debugger, but rather a panel where you can see variable values, ticks, and flags in real time. Where you can pause to check what a specific NPC is doing, change its behavior, enable debug information, and see how many bugs disappear simply because you finally noticed what's going on in the game logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Programming
&lt;/h2&gt;

&lt;p&gt;It may seem strange, but traditional programming practices aren't mandatory for implementing game logic, and it'd be enough to explore visual programming systems (Blueprints, VisualScript, and ICS), which have been around for decades and allow developers to create complex mechanics without writing code manually. These systems are especially popular among designers and artists who want to prototype ideas quickly, without diving into the programming language syntax.&lt;/p&gt;

&lt;p&gt;Designers do write code; visual programming is a legitimate form of programming, it's just that constructs like &lt;code&gt;class&lt;/code&gt;, &lt;code&gt;if&lt;/code&gt;, and &lt;code&gt;for&lt;/code&gt; have another form. However, the essence lies not in forms, but in practical aspects. If you want to implement visual scripting in the game engine, you'll need to create specialized tools: node editors, visual debuggers, data-flow diagrams, optimizers, and much more. This significantly complicates engine development. For example, in Unreal Engine, Blueprints are backed by a huge amount of low-level C++ code, comparable in scale to the renderer or animation engine.&lt;/p&gt;

&lt;p&gt;Classic code remains the most versatile and flexible way to implement logic, but it's gradually losing ground. It doesn't depend on the limitations of visual tools and allows working closer to system-level resources. However, the classic approach entails well-known problems, such as recompilation, halting the engine for rebuilds, and the time lost in these processes. And it's worth noting that training designers to work with different programming languages (for example, C++) results in high financial and time investment, and the cost of a mistake is the same as for a game programmer—an error can still crash the engine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Main window
&lt;/h2&gt;

&lt;p&gt;Most games need a window to run in—even browser games are no exception here. The window can be either the entire web page or a specific &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; element where the game is executed. Windows are usually created using platform-dependent mechanisms. These low-level interfaces are often cumbersome and inconvenient. What's more, you need to write separate code once for each platform (Windows, Linux, macOS, iOS, or Android) to create a window—but you rarely revisit this block afterward.&lt;/p&gt;

&lt;p&gt;You need not only the window; there is also a graphics API context (OpenGL, Vulkan, or DirectX), which is also created via messy platform-dependent calls. Once again: you either implement them once yourself, or use a ready-made library (SDL2, GLFW, SFML, or one of many others). After creating the window, the next step is to set up the game loop—this is what will handle events, update the game logic, and render each frame.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gameplay loop
&lt;/h2&gt;

&lt;p&gt;The gameplay loop is what unites all games and game engines, although it may be veiled within the engine, replaced by abstractions or handler functions (callbacks). Ultimately, the gameplay loop code looks 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="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;createWindow&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="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isRunning&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputEvent&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;updateFrame&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;drawFrame&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;shutdown&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;destroyWindow&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 gameplay loop runs the game—without it, the &lt;code&gt;main&lt;/code&gt; function would just end, causing the game to crash. There are many ways to expose a loop using the engine's API: it can be fully explicit, when the engine user writes something like &lt;code&gt;while(engine::isRunning())&lt;/code&gt; in their &lt;code&gt;main&lt;/code&gt; function, or find it in the depths of the engine, for example, in some function like &lt;code&gt;engine::run()&lt;/code&gt;, which in turn calls some user-defined functions (callbacks). Whatever you choose, you'll still need a gameplay loop.&lt;/p&gt;

&lt;h2&gt;
  
  
  User input
&lt;/h2&gt;

&lt;p&gt;This is one of the foundations of any game, even if the player only has to click a pixelized cookie. The most basic input processing relies on platform-dependent APIs (WinAPI, X11, or Cocoa), which are often awkward to work with: they're not complex, but very verbose and require separate code for each supported platform. However, almost all of these APIs can extract events into an event-handling function (for example, &lt;code&gt;Game::pollEvents()&lt;/code&gt;), which can be used to retrieve user events sequentially.&lt;/p&gt;

&lt;p&gt;When it's time to integrate input into the game engine, you can use various approaches. One option is to provide users with direct access to the event system. In this case, the game developer calls events via &lt;code&gt;pollEvent()&lt;/code&gt; and decides how to handle them. The basic structure of event processing usually looks like this: in the gameplay loop, the event-handling function is called at each iteration, parsing all incoming events are sequentially. Depending on the event type, the corresponding functions are called or appropriate actions are performed—for example, handling mouse movement, keyboard input, or window closing. This approach provides maximum flexibility but requires the developer to write numerous code lines and understand the event structure.&lt;/p&gt;

&lt;p&gt;In practice, most game developers rely on cross-platform libraries or built-in input systems in game engines like Unity, Unreal Engine, or Godot. These solutions handle the low-level, messy interaction with the OS and expose a unified and user-friendly interface for processing keyboard, mouse, gamepad, and touch input. Here's an 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;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isRunning&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Event&lt;/span&gt; &lt;span class="n"&gt;event&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;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pollEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&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;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&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="n"&gt;Event&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;MouseMove&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
        &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;onMouseMove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mouseX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mouseY&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="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;Event&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;KeyPressed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;onKeyPressed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keyCode&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="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;Event&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;WindowClose&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quit&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="n"&gt;engine&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="c1"&gt;// Game logic&lt;/span&gt;
  &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Frame rendering&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another option is to integrate event handling directly into the engine and provide the user only with calls to handler functions. It accelerates and streamlines early development. However, it requires a well-designed architecture for registering these functions.&lt;/p&gt;

&lt;p&gt;This approach makes life much easier for game developers, especially at the early stages of a project. Instead of manually querying input devices and processing complex event logic, developers simply register handlers for the events they're interested in—key presses, mouse movements, or screen touches.&lt;/p&gt;

&lt;p&gt;The appropriate handlers are invoked at the right moment, with all the necessary event information about passed to them. This approach works well for simple games and prototypes, where rapid development is a priority and complex interaction logic isn't yet required. Popular libraries (frameworks) implement this event-driven model, but as a project grows in complexity, this architecture can become a source of problems. The main difficulty lies in creating a flexible system for registering and managing event handlers—callbacks must be easy to add and remove during execution, priorities may need to be set, and events may need to be filtered by game context. With many registered handlers, each event can trigger a chain of calls that were not initially anticipated. Here's an example of 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="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;onMouseMove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MouseEvent&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;onMouseMove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mouseX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mouseY&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;onKeyPressed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;KbEvent&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;onKeyPressed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keyCode&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;onWindowClose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AppCloseEvent&lt;/span&gt; &lt;span class="n"&gt;ev&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quit&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;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;onMouseMove&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;onKeyPressed&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;onWindowClose&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;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isRunning&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Event&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;updateFrame&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;engine&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="c1"&gt;// Game logic&lt;/span&gt;
    &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Frame rendering&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;h2&gt;
  
  
  Graphics
&lt;/h2&gt;

&lt;p&gt;You got the main window and even teach your program to react on mouse and keyboard, but... You can't &lt;em&gt;see&lt;/em&gt; its response—graphics comes to the stage. Honestly, I struggle with 3D graphics and am always jealous of my friend, @megai2, who can easily render everything for any platform, from consoles to mobile devices. Fortunately, most libraries for creating windows, like SDL, already provide support for 2D graphics. You can draw directly to the window, use textures, or even fill pixels with any colors. It's basic but honest.&lt;/p&gt;

&lt;p&gt;Let's say the engine is optimized for 2D games built around tiles and sprites. Then, most likely, you'll have to implement something like &lt;code&gt;drawSprite(image, x, y)&lt;/code&gt;, possibly with support for all sorts of delightful features: scaling, rotation, blending, desaturation, and alpha blending. Internally, you can manually implement it either by directly copying pixels (with/without evaluations and blitting), or by relying on another library like Cairo. It turns out to be a very good renderer, capable of doing if not everything, then at least a great deal. You can also do it via OpenGL/DX/Vulkan, if your heart craves hardcore performance.&lt;/p&gt;

&lt;p&gt;That's not the only option, you might also choose not to specialize at all and simply give the user a set of general-purpose APIs for the engine, as most SDL/SFML/Allegro libraries do—let them figure it out for themselves. In my implementation for the Pharaoh project, there is a wrapper over SDL (which supports native GAPI), but there is no full-fledged renderer in the usual sense. I wrote a new rendering system for each engine. On the one hand, it wasn't easy, but on the other, I had a chance to experiment with graphics to my heart's content.&lt;/p&gt;

&lt;p&gt;No matter how the rendering system is built, sooner or later, you'll need to display text for the interface, debugging information, and other purposes. Yes, you can draw letters manually pixel by pixel, but it's better to use a standard library like FreeType. For eager fans of bizarre adventures and Unicode, HarfBuzz is worth exploring.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;Once upon a time, you finalize another level, try to run the build, and... it takes about a whole minute to run. Then two. And then you notice that some stage "weighs" 2 GB, because each tree is an object with a unique copy of texture and models. That's when it becomes clear: it's time for resource management.&lt;/p&gt;

&lt;p&gt;Resource management is hidden from users, but defines whether the game will be responsive and even run at all. First, it would be wise to pack resources into archives: opening a thousand files from a disk is a major drawback of OS interaction. The platform may be slow, the file system may not be very responsive, and the player's SSD might not match what you expected in the studio.&lt;/p&gt;

&lt;p&gt;Therefore, everything gets packed: textures, models, sounds, levels, and scripts. Using a custom container format with indexing and compression is widespread, but some people use ready-made ones like Oodle, ZIP. Others create virtual file systems tailored to the engine's needs. Large commercial engines, by the way, usually follow this path. Archives are easy to distribute, easy to cache, and no one digs around... except the ones who really want to.&lt;/p&gt;

&lt;p&gt;For example, you can compile all resources into one large binary &lt;code&gt;blob&lt;/code&gt; and embed them into the executable file, as many games have done and continue to do. That's what Xbox and Sony did at first. What are the advantages? Everything is on hand and fast—no extra loadings, no paths to files—just grab a byte array and work with it as you would with a resource. In some projects, this approach quite literally saved releases and helped pass certification. Sure, that might leave you with a 700 MB binary file, but it's all because of the "my cat fell on the keyboard" moment and "the junior who wrote the templates crashed everything.".&lt;/p&gt;

&lt;p&gt;Indeed, there are drawbacks: you can't change any asset without recompiling the entire game. Even if you just want to adjust a pixel color in a texture, you have to wait for a rebuild. It also makes modding virtually impossible: how would players add their funny custom hats if all content is "sealed" inside the &lt;code&gt;.exe&lt;/code&gt; file?&lt;/p&gt;

&lt;p&gt;You can store resources as regular files in the &lt;code&gt;assets/&lt;/code&gt; directory next to the executable file. Then the engine simply loads the necessary file when the level starts, if you haven't factored in performance. This is the best approach for development: it's fast, clear, and you can open the folder at any time, swap a texture, and see the changes in the game. And it's also a real gift for modders: they can just take it, tweak it, add to it—everything is open.&lt;/p&gt;

&lt;p&gt;Regardless of how assets are stored, they still need to be converted from raw bytes into meaningful data. For this, you typically rely on format libraries—for example, &lt;code&gt;stb_image&lt;/code&gt; to convert PNG to pixel arrays or various JSON libraries to extract information about entities from &lt;code&gt;.json&lt;/code&gt;-like configuration files, if you haven't yet become disillusioned with JSON as a format for such files. At some point, the team realizes that a purely declarative configuration format is not enough, and then a VM (Virtual Machine) for JS/Lua/Squirrel/AngelScript is added to the engine. These are scripting languages, but in this context, they're used for parsing configurations.&lt;/p&gt;

&lt;p&gt;In many projects, developers eventually move to custom formats or adopt a higher-level language, which, in practice, also leads to using a virtual machine or interpreter.&lt;/p&gt;

&lt;p&gt;And you can—I would say you should—enable hot reloading of assets as a second step after the configurations, so that you don't have to restart the game a thousand times a day. You change the picture, sound, or configuration, and boom—they're right in your game. Pure magic? No, it's just another reason why the resource manager grows into a monster that affects the entire engine.&lt;/p&gt;

&lt;p&gt;Resources aren't just a development concern—they also play a key role in the release process. The system must generate builds for different platforms: Windows, Linux, consoles, Steam Deck, and others. Each platform comes with its own constraints and requirements for data alignment, supported formats, and packaging rules. For example, some platforms do not allow MP3 files, while others do not support certain texture formats.&lt;/p&gt;

&lt;p&gt;Finally, one of the trendiest and most important features is automatic updates and patches. The player must not have to download extra 10 GB if you changed one texture. My build system calculates deltas: which files have changed, how they can be compressed, and where to place them. The launcher checks versions and downloads only what is missing. And if something goes wrong, it can roll back. And honestly, players appreciate this more than almost anything else, when the game "updates itself and just works".&lt;/p&gt;

&lt;h2&gt;
  
  
  Audio output
&lt;/h2&gt;

&lt;p&gt;In case you didn't know, audio output is a nightmare with platform-dependent APIs. They're ugly, unintuitive, and downright capricious; XBox has a habit of throwing exceptions if you write too much to the buffer, but... well, if you write less than the buffer's allocated size, it'll throw exceptions too. Audio output is just my hobby...I mean, I'm not an expert here, but even a little hands-on experience was enough to understand: if you just want to reproduce sound, get ready to suffer.&lt;/p&gt;

&lt;p&gt;Or... you can just use a library that hides all this nightmare behind a clean interface, for example, OpenAL or SDL. Recently, I've been using the latter because it's very forgiving of mistakes, even if you blundered. These libraries usually expect the engine to provide the audio callback, a function that the system will call (usually from a separate thread) dozens or even hundreds of times per second.&lt;/p&gt;

&lt;p&gt;Each call requires returning a small chunk of audio data. Maybe you just want silence. Maybe a single MP3 playing in the background. But most likely, you'll need a little more: music, effects, voice. Each in different streams, with different volume, with smooth fades, no clicks or pops, no tremors, add some reverb or other effects... well, you catch the point.&lt;/p&gt;

&lt;p&gt;To ensure its stability, you need a mixer. Not a cooking machine, of course (though sometimes that wouldn't hurt), but an audio mixer—a library that will combine multiple audio streams into one, carefully control their volume, filter sharp peaks, apply effects, and prevent the sound from turning into a mess when a battle breaks out with 15 different unit sounds, fanfare, and alarming music.&lt;/p&gt;

&lt;p&gt;A good engine usually implements its own audio mixer. It can be large and complex—with crossfading, reverb, effects, and post-processing—or it can be simple, with just a few channels and background music. But the idea is always the same: the mixer works with abstract sound streams, combines them, and produces a single output stream sent to the audio device.&lt;/p&gt;

&lt;p&gt;Writing your own mixer at least once is a great way to understand how it works. Of course, you can also rely on existing libraries that already handle mixing, balancing, compression, and other audio processing tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Physics
&lt;/h2&gt;

&lt;p&gt;To be honest... most games don't actually need physics. I mean real physics—with forces, momentum, friction, and all that scientific stuff. Most people want something simpler: animations, logic, and scripts—things that &lt;em&gt;look&lt;/em&gt; like physics without having much to do with it. For example, look at Civilization VI, one of the most complex strategy games of our time—the game has no need in physics implementation at all. Or take a peek at various city-building simulators (such as SimCity)—obviously, houses don't collapse, roads don't crack, and no one calculates the fall vector of a water tower because it's not necessary. So, why complicate things? Yet, somehow both Civ and Cities Skylines drag dependencies onto PhysX, maybe they actually use them, maybe not. Who knows.&lt;/p&gt;

&lt;p&gt;Platformers or 2D RPGs don't need much physics too—it usually consists of character movement and simple collisions with walls, enemies, and boxes. You can write that in a couple of evenings, unless, of course, you get stuck on every line, as I did, trying to wrap my mind around it. The main thing is that everything will be under control: if you want the hero to slide like they're on ice, please do so. Enemies should bounce off when colliding like rubber ducks? Come on, give it a try.&lt;/p&gt;

&lt;p&gt;If collisions start pilling up and performance drops, you can optimize it. Spatial hashing, quadtrees, and distance constraints from MC. But... if you're stubborn and know for sure that you need real physics, go for a ready-made library: Box2D for 2D or Bullet for 3D. Don't reinvent the wheel; you will have plenty of time to create them on the self-written engine.&lt;/p&gt;

&lt;p&gt;And if you want to understand how such engines work under the hood, it's best to watch a YouTube video from the Box2D creator. He explains physics with impulses in a way that provides a rare insight into the mechanics. I used to think that physics was about mass, speed, and formulas, but now I know that real physics is when you're up at 3 a.m. trying to figure out why a character is stuck on a staircase because the collision mesh didn't load.&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;

</description>
      <category>cpp</category>
      <category>gamedev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Webinar: Let's make a programming language. Intro— Key points</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Tue, 07 Apr 2026 11:48:38 +0000</pubDate>
      <link>https://forem.com/pvsdev/webinar-lets-make-a-programming-language-intro-why-would-you-want-to-create-your-own-programming-37e2</link>
      <guid>https://forem.com/pvsdev/webinar-lets-make-a-programming-language-intro-why-would-you-want-to-create-your-own-programming-37e2</guid>
      <description>&lt;p&gt;We're happy to present the first part in a webinar series on creating your own programming language. If you've ever wondered what it takes to build your own language from scratch, this series is for you.&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 creating your own programming language, step by step.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why would you want to create your own programming language?
&lt;/h3&gt;

&lt;p&gt;You may ask us or our speaker, "What's the point? There are plenty of other languages!"&lt;/p&gt;

&lt;p&gt;First of all, it's fun! Plus, if you want to enhance your programming skills and truly understand how your favorite language works, building a programming language can provide foundational knowledge of compiler internals and foster a deep appreciation for language design and implementation.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's in the "black box"?
&lt;/h3&gt;

&lt;p&gt;The webinar outlines the entire structure of a compiler or an interpreter, focusing on the "black box" that transforms human-readable source code into executable output or runtime results. Yuri briefly covers its core components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;lexer&lt;/strong&gt; that divides the input into smaller parts—tokens—and tags them;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;parser&lt;/strong&gt; that operates on grammatic rules to understand the input and uses those tokens to build a syntax tree;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;semantics&lt;/strong&gt; that gives the syntax meaning and recognizes function names, data types, etc.;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;evaluator&lt;/strong&gt; that is a part of an optimization pipeline.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the first session, Yuri introduces these concepts at a high level; future webinars will delve deeper into all aspects of the language under the expert guidance of our speaker. Everything will be explained step by step, so you can easily follow along.&lt;/p&gt;

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

&lt;p&gt;If you want to familirize with other webinars or see the whole webinar, &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=web3" 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/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 how a lexer is actually implemented in code.&lt;/p&gt;

&lt;p&gt;If you'd like to look closer what we do, check out our &lt;a href="https://pvs-studio.com/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=webinar&amp;amp;utm_content=web3" rel="noopener noreferrer"&gt;website&lt;/a&gt;.&lt;/p&gt;

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

</description>
      <category>programming</category>
      <category>webinar</category>
      <category>cpp</category>
    </item>
    <item>
      <title>Webinar: Integrating SAST into DevSecOps — Key Points</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Mon, 06 Apr 2026 14:14:33 +0000</pubDate>
      <link>https://forem.com/pvsdev/webinar-integrating-sast-into-devsecops-key-points-4gno</link>
      <guid>https://forem.com/pvsdev/webinar-integrating-sast-into-devsecops-key-points-4gno</guid>
      <description>&lt;p&gt;Today, we'd like to share with you our full video from the webinar 'Integrating SAST into DevSecOps'.&lt;/p&gt;

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

&lt;p&gt;Anton Tretyakov, an experienced DevOps engineer at PVS-Studio who builds and maintains the static analyzer infrastructure. He also writes about C++ in his spare time. During the webinar, Anton shares his insights on modernizing code security, seamlessly integrating static analysis tools into security workflows, and optimizing existing pipelines.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key points
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is SAST?
&lt;/h3&gt;

&lt;p&gt;Static application security testing (SAST) is a security check that automatically analyzes your code for errors and weak points without executing it. Unlike regular static analysis, a SAST tool detects potential vulnerabilities, not regular bugs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bugs vs Vulnerabilities
&lt;/h3&gt;

&lt;p&gt;It's impossible to predict whether a bug will affect a program's behavior. A bug becomes a potential vulnerability when possible consequences of its presence in the source code are clearly defined. A potential vulnerability turns into a real one when it slips into real software and is exploited by a malicious user.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does SAST work?
&lt;/h3&gt;

&lt;p&gt;A SAST tool automates the tedious process of manually looking through every code line. To do this, it uses a syntax tree containing all the variables in a program. It scans the code for errors and issues a warning when it detects a flaw or potential undefined behavior that may harm the application.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to integrate SAST into DevSecOps?
&lt;/h3&gt;

&lt;p&gt;Early detection reduces the cost of fixing an error, so it is crucial to integrate a SAST tool into the development workflow as early as possible.&lt;/p&gt;

&lt;p&gt;To check code, a SAST tool needs only a compilable project. Compared to other usual checks in a pipeline, static analysis provides comprehensive coverage of the whole program codebase. It works best when used together with other tests and checks. &lt;/p&gt;

&lt;p&gt;Here's an example of how you can integrate static analysis into your pipeline: &lt;/p&gt;

&lt;p&gt;build the project &amp;gt; pass credentials to the analyzer &amp;gt; run the analysis &amp;gt; get the analyzer report &amp;gt; extract metrics information from the report &amp;gt; export the metrics file to the Merge Request &amp;gt; move on to other development stages. &lt;/p&gt;

&lt;h3&gt;
  
  
  How to use SAST on legacy code
&lt;/h3&gt;

&lt;p&gt;Static analysis detects various types of errors and can be used as the quality gate mechanism. When you work on a big project that also contains legacy code, you can see thousands of warnings issued by the analyzer. Sifting through them all is a really time-consuming and tedious task. This is where the one-direction approach comes into play. &lt;/p&gt;

&lt;p&gt;Learn more: &lt;a href="https://pvs-studio.com/en/blog/posts/0743/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=webinar&amp;amp;utm_content=integrating_sast" rel="noopener noreferrer"&gt;How to introduce a static code analyzer in a legacy project and not to discourage the team&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How to use SAST as quality gate
&lt;/h3&gt;

&lt;p&gt;PVS-Studio static analyzer allows running the analysis for the first time to save issued warnings in your database. Regularly check your project so that the tool can determine whether any changes have occurred. If the number of warnings increases, the changes to the repository are denied. &lt;/p&gt;

&lt;p&gt;Learn more: &lt;a href="https://pvs-studio.com/en/blog/posts/1264/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=webinar&amp;amp;utm_content=integrating_sast" rel="noopener noreferrer"&gt;Static analysis for pull requests. Another step towards regularity&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;That's only a part of the whole content that was covered during the session. If you want to learn more and see the whole webinar and look closer at slides, follow the link: &lt;a href="https://pvs-studio.com/en/blog/video/11582/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=webinar&amp;amp;utm_content=integrating_sast" rel="noopener noreferrer"&gt;Integrating SAST into DevSecOps&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/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, the speaker will walk you through how a lexer is actually implemented in code. &lt;/p&gt;

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

</description>
      <category>devsecops</category>
      <category>devops</category>
      <category>cybersecurity</category>
      <category>cicd</category>
    </item>
    <item>
      <title>Builds &amp; Bugs: Which RPG class are you as a developer?</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Wed, 01 Apr 2026 14:38:10 +0000</pubDate>
      <link>https://forem.com/pvsdev/builds-bugs-which-rpg-class-are-you-as-a-developer-4jl4</link>
      <guid>https://forem.com/pvsdev/builds-bugs-which-rpg-class-are-you-as-a-developer-4jl4</guid>
      <description>&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%2F11zj21cjvwl5csrjf0dn.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%2F11zj21cjvwl5csrjf0dn.png" alt=" " width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every developer's working days turn into routine sooner or later (even if everything feels inspiring and exciting to a freshly minted junior at first). Over time, the novelty wears off, confidence grows with seniority, and the next code review stops feeling like a thrilling challenge and becomes just another part of the workflow. Been there? &lt;/p&gt;

&lt;p&gt;What if there was a different way to look at it? After all, "what is life but a game?" Seen that way, any project can become a real adventure. And every adventure needs brave heroes ready to fight bugs monsters. Turns out, you're one of them.&lt;/p&gt;

&lt;p&gt;Whether you're into tabletop RPGs or digital ones, the classic archetypes are hard to miss: mages, warriors, rogues, and the rest. So, take a short break from the routine, &lt;a href="https://pvs-studio.com/en/blog/questionnaires/developer-rpg-class/" rel="noopener noreferrer"&gt;answer a few questions&lt;/a&gt;, and try on the role of one of seven heroes. There's also something useful waiting at the end—a little help for your future battles with bugs.&lt;/p&gt;

</description>
      <category>quiz</category>
      <category>developer</category>
      <category>marketing</category>
    </item>
    <item>
      <title>How catch-block selection works in exception handling</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Tue, 31 Mar 2026 13:44:29 +0000</pubDate>
      <link>https://forem.com/pvsdev/how-catch-block-selection-works-in-exception-handling-1921</link>
      <guid>https://forem.com/pvsdev/how-catch-block-selection-works-in-exception-handling-1921</guid>
      <description>&lt;p&gt;If a pill knows what to treat, could an exception also understand when to stop its journey through the stack? In application programming, a description like this is often enough, but sometimes one wants more details. Well, let's dive in!&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%2Fh5fb7ma62p8gm3y4uz0i.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%2Fh5fb7ma62p8gm3y4uz0i.png" alt="1360_LinuxExceptionTwo/image1.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/cpp/1333/" rel="noopener noreferrer"&gt;Last time&lt;/a&gt;, we looked at how exceptions are thrown and caught, as well as the connection between these two processes. We've seen functions of the &lt;code&gt;__cxa*&lt;/code&gt; and &lt;code&gt;_Unwind*&lt;/code&gt; families, how they intertwine, and how the compiler embeds some of them into assembly code along with additional code blocks when compiling programs. &lt;/p&gt;

&lt;p&gt;Some questions still remain unanswered. We've moved on from SjLj exceptions, and we've paused the discussion of zero-cost exceptions at the most thrilling point: the personality routine. In this article, we'll pick up right where we left off to answer the question, "How does an exception know it has reached the right &lt;code&gt;catch&lt;/code&gt; block?"&lt;/p&gt;

&lt;p&gt;Just like last time, we'll be using the &lt;code&gt;libcxx&lt;/code&gt; library from LLVM. We'll also use the same compiler, Clang 21.1.0 for x86-64.&lt;/p&gt;

&lt;h2&gt;
  
  
  Previously...
&lt;/h2&gt;

&lt;p&gt;While exploring the inner workings of the system, we came across two functions, &lt;a href="https://github.com/llvm/llvm-project/blob/bd0769ef869a1341e8122978e1eafc78c5f3d312/libunwind/src/UnwindLevel1.c#L467" rel="noopener noreferrer"&gt;&lt;code&gt;_Unwind_RaiseException&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/UnwindLevel1.c#L525" rel="noopener noreferrer"&gt;&lt;code&gt;_Unwind_ForcedUnwind&lt;/code&gt;&lt;/a&gt;, and thoroughly looked into how they work. The second function, which involved forced stack unwinding, was less exciting since it had no direct connection to our topic. However, the first one paved the way for understanding how exceptions are delivered through the program stack. It was executed in two stages: locating the appropriate &lt;code&gt;catch&lt;/code&gt; block, and then delivering the exception along with calling automatic variable destructors.&lt;/p&gt;

&lt;p&gt;While the stack traversal part is now clear, the process of determining the correct exception handler remains a mystery. All we know about how it works is that at some point during the execution of both stages, &lt;a href="https://github.com/llvm/llvm-project/blob/bd0769ef869a1341e8122978e1eafc78c5f3d312/libunwind/src/UnwindLevel1.c#L297" rel="noopener noreferrer"&gt;code like this executes&lt;/a&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;_Unwind_Personality_Fn&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_handler_function&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;frameInfo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="c1"&gt;// ....&lt;/span&gt;
&lt;span class="n"&gt;_Unwind_Reason_Code&lt;/span&gt; &lt;span class="n"&gt;personalityResult&lt;/span&gt; &lt;span class="o"&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;p&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;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exception_object&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;exception_class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;exception_object&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;_Unwind_Context&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;cursor&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 the code, the &lt;code&gt;frameInfo&lt;/code&gt; variable of the &lt;a href="https://github.com/llvm/llvm-project/blob/9e25a423d07bdcc2686defedcd509fb405d250db/libunwind/include/libunwind.h#L193" rel="noopener noreferrer"&gt;&lt;code&gt;unw_proc_info_t&lt;/code&gt;&lt;/a&gt; type is used to retrieve &lt;code&gt;handler&lt;/code&gt;, which is a function that determines when to stop stack unwinding. We can see that calling the &lt;code&gt;p&lt;/code&gt; function returns some result. The calling stack unwinding driver uses this result to determine what to do next with the unwinding.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;frameInfo&lt;/code&gt; variable contains important information: a pointer to the &lt;code&gt;handler&lt;/code&gt; itself and several other data members. They include pointers to the start and end of the function whose stack frame is being evaluated at the current stack unwinding stage, as well as other details.&lt;/p&gt;

&lt;p&gt;In the previous article, we encountered the &lt;code&gt;__gxx_personality_v0&lt;/code&gt; symbol, which was defined in the assembly code that Clang generated from our test project. This symbol may be related to the &lt;code&gt;handler&lt;/code&gt;, but we haven't proven it yet.&lt;/p&gt;

&lt;p&gt;Let's revisit this project's 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="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;bar&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="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="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&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;bar&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;catch&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="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="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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;foo&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 convert it to &lt;a href="https://godbolt.org/z/vhMnrj6a6" rel="noopener noreferrer"&gt;assembly code&lt;/a&gt; and work with that.&lt;/p&gt;

&lt;p&gt;Assembly 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="n"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;push&lt;/span&gt;    &lt;span class="n"&gt;rbp&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rsp&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;edi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_allocate_exception&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rdi&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;mov&lt;/span&gt;     &lt;span class="n"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rip&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;typeinfo&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;GOTPCREL&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;xor&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;edx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_throw&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;

&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;push&lt;/span&gt;    &lt;span class="n"&gt;rbp&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rsp&lt;/span&gt;
        &lt;span class="n"&gt;sub&lt;/span&gt;     &lt;span class="n"&gt;rsp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&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;eax&lt;/span&gt;
        &lt;span class="n"&gt;jmp&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_1&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&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;add&lt;/span&gt;     &lt;span class="n"&gt;rsp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
        &lt;span class="n"&gt;pop&lt;/span&gt;     &lt;span class="n"&gt;rbp&lt;/span&gt;
        &lt;span class="n"&gt;ret&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rcx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;edx&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&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="n"&gt;rcx&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&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="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_begin_catch&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;edi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_allocate_exception&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rdi&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;mov&lt;/span&gt;     &lt;span class="n"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rip&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;typeinfo&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;GOTPCREL&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;xor&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;edx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_throw&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;jmp&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_8&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rcx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;edx&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&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="n"&gt;rcx&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_end_catch&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;jmp&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_5&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_5&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;jmp&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_6&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_6&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&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="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;_Unwind_Resume&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rax&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__clang_call_terminate&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_8&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;

&lt;span class="n"&gt;__clang_call_terminate&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;push&lt;/span&gt;    &lt;span class="n"&gt;rbp&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rsp&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_begin_catch&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;call&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;terminate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;

&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;push&lt;/span&gt;    &lt;span class="n"&gt;rbp&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rsp&lt;/span&gt;
        &lt;span class="n"&gt;sub&lt;/span&gt;     &lt;span class="n"&gt;rsp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&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="mi"&gt;0&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;add&lt;/span&gt;     &lt;span class="n"&gt;rsp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
        &lt;span class="n"&gt;pop&lt;/span&gt;     &lt;span class="n"&gt;rbp&lt;/span&gt;
        &lt;span class="n"&gt;ret&lt;/span&gt;

&lt;span class="n"&gt;DW&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__gxx_personality_v0&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="n"&gt;__gxx_personality_v0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What if we just search for the &lt;code&gt;__gxx_personality_v0&lt;/code&gt; symbol in the &lt;code&gt;libcxx&lt;/code&gt; library code? Well, we'll &lt;a href="https://github.com/llvm/llvm-project/blob/bd0769ef869a1341e8122978e1eafc78c5f3d312/libcxxabi/src/cxa_personality.cpp#L1029" rel="noopener noreferrer"&gt;find it&lt;/a&gt;. Cool, thanks...&lt;/p&gt;

&lt;p&gt;It's scary and confusing, but the most important thing is that we can't yet see a direct connection between this function and that &lt;code&gt;handler&lt;/code&gt;. Well, let's try to determine it!&lt;/p&gt;

&lt;h2&gt;
  
  
  libunwind
&lt;/h2&gt;

&lt;p&gt;We know one thing for certain: the &lt;code&gt;handler&lt;/code&gt; is retrieved from a structure of the &lt;a href="https://github.com/llvm/llvm-project/blob/9e25a423d07bdcc2686defedcd509fb405d250db/libunwind/include/libunwind.h#L193" rel="noopener noreferrer"&gt;&lt;code&gt;unw_proc_info_t&lt;/code&gt;&lt;/a&gt; type. It contains information about the function that created the current stack frame, as well as additional information needed to unwind the stack. &lt;/p&gt;

&lt;h3&gt;
  
  
  A super-quick introduction to libunwind
&lt;/h3&gt;

&lt;p&gt;To trace the connection between the personality routine and this structure, we first need to understand where the structure gets populated. That means diving into the &lt;code&gt;libunwind&lt;/code&gt; library. This library enables reading of function stack frames. We'll take a look at how its context initialization works under the hood, the data structure it uses to reference stack frames during unwinding, and how those structures are populated.&lt;/p&gt;

&lt;p&gt;To move forward, let's go over the basics of working with &lt;code&gt;libunwind&lt;/code&gt;. We can use the structure of the &lt;code&gt;unw_cursor_t&lt;/code&gt; type to tell the library which frame we want to read. It's somewhat of a handler that enables us to traverse the stack. We get the frame information directly from the already familiar &lt;code&gt;unw_proc_info_t&lt;/code&gt; structure. The cursor itself is retrieved from a context, which is a structure of the &lt;code&gt;unw_context_t&lt;/code&gt; type. Once this structure is initialized, &lt;code&gt;libunwind&lt;/code&gt; is ready to use.&lt;/p&gt;

&lt;h3&gt;
  
  
  The libunwind context
&lt;/h3&gt;

&lt;p&gt;In our case, &lt;code&gt;libunwind&lt;/code&gt; gets initialized in &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/UnwindLevel1.c#L470" rel="noopener noreferrer"&gt;&lt;code&gt;_Unwind_RaiseException&lt;/code&gt;&lt;/a&gt;, which we covered in the previous article. It serves as the entry point to the stack unwinding driver when an exception is thrown and is called almost immediately after it occurs. This happens within the abstraction layer defined by the &lt;code&gt;the _cxa&lt;/code&gt; family of functions.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;libunwind&lt;/code&gt; initialization in this function looks 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;unw_context_t&lt;/span&gt; &lt;span class="n"&gt;uc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;unw_cursor_t&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;__unw_getcontext&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;uc&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are two new types here: &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/include/libunwind.h#L173" rel="noopener noreferrer"&gt;&lt;code&gt;unw_context_t&lt;/code&gt; and &lt;code&gt;unw_cursor_t&lt;/code&gt;&lt;/a&gt;. They have similar definitions: both contain data stored in arrays whose lengths are determined at compile time. It's impossible to say exactly what's stored there, since the data is located in a 64-bit unsigned integer array. This means that the types are opaque wrappers around other structures that are implementation details of the library. We can determine where the data is populated, though!&lt;/p&gt;

&lt;p&gt;As we can see from the code of the &lt;code&gt;_Unwind_RaiseException&lt;/code&gt; function, the &lt;code&gt;unw_context_t&lt;/code&gt; struct is populated in the &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/UnwindRegistersSave.S#L123" rel="noopener noreferrer"&gt;&lt;code&gt;__unw_getcontext&lt;/code&gt;&lt;/a&gt; function.&lt;/p&gt;

&lt;p&gt;Wow, we reached assembly code pretty quickly this time! It does fairly straightforward work—saving the register state into the &lt;code&gt;unw_context_t&lt;/code&gt; structure, whose pointer we conveniently passed into the function beforehand. This function has platform-specific implementations that ensure the array within this struct is populated correctly. &lt;/p&gt;

&lt;p&gt;Okay, a bunch of &lt;code&gt;movq&lt;/code&gt; statements means that &lt;code&gt;libunwind&lt;/code&gt; is initialized by saving the function register state where the operation begins. In our case, this is &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/UnwindLevel1.c#L470" rel="noopener noreferrer"&gt;&lt;code&gt;_Unwind_RaiseException&lt;/code&gt;&lt;/a&gt;, the main stack unwinding driver. This makes sense, since above this function frame are the frames of our program's functions where the exception was thrown.&lt;/p&gt;

&lt;p&gt;Okay, where is the &lt;code&gt;unw_cursor_t&lt;/code&gt; structure populated?&lt;/p&gt;

&lt;h3&gt;
  
  
  The libunwind cursor
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/UnwindLevel1.c#L470" rel="noopener noreferrer"&gt;&lt;code&gt;Unwind_RaiseException&lt;/code&gt;&lt;/a&gt; consists of two phases, which we covered in the &lt;a href="https://pvs-studio.com/en/blog/posts/cpp/1333/" rel="noopener noreferrer"&gt;previous article&lt;/a&gt;. Let's take a look at the &lt;a href="https://github.com/llvm/llvm-project/blob/bd0769ef869a1341e8122978e1eafc78c5f3d312/libunwind/src/UnwindLevel1.c#L111" rel="noopener noreferrer"&gt;beginning of the first phase&lt;/a&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;static&lt;/span&gt; &lt;span class="n"&gt;_Unwind_Reason_Code&lt;/span&gt;
&lt;span class="nf"&gt;unwind_phase1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unw_context_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;uc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="n"&gt;unw_cursor_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="n"&gt;_Unwind_Exception&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;exception_object&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;__unw_init_local&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;uc&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 can see pointers to the context and the cursor being passed down from the &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/UnwindLevel1.c#L470" rel="noopener noreferrer"&gt;&lt;code&gt;_Unwind_RaiseException&lt;/code&gt;&lt;/a&gt; function. We can also see the &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/libunwind.cpp#L43" rel="noopener noreferrer"&gt;&lt;code&gt;__unw_init_local&lt;/code&gt;&lt;/a&gt; function, which receives those pointers. From this point on, things are about to get really interesting. This function determines the register type for the target platform. In reality, however, the compiler fixes this at compile time. Then, the function constructs a new &lt;code&gt;UnwindCursor&lt;/code&gt; object using &lt;em&gt;placement new&lt;/em&gt; inside the array stored in the &lt;code&gt;unw_cursor_t&lt;/code&gt; struct.&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;// Use "placement new" to allocate UnwindCursor in the cursor buffer.&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;reinterpret_cast&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;UnwindCursor&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;LocalAddressSpace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;REGISTER_KIND&lt;/span&gt;&lt;span class="o"&gt;&amp;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="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;UnwindCursor&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;LocalAddressSpace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;REGISTER_KIND&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;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LocalAddressSpace&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;sThisAddressSpace&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 way, you might recall that we came across the &lt;code&gt;UnwindCursor&lt;/code&gt; type in the previous article. We saw how it handles jumping to the correct point in the program via the &lt;a href="https://github.com/llvm/llvm-project/blob/4237ec343a7f0c0d3717972b14ae22ec10ff74cd/libunwind/src/UnwindCursor.hpp#L1428" rel="noopener noreferrer"&gt;jumpto&lt;/a&gt; function. That's why we'll take a closer look at it! In any case, &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/UnwindCursor.hpp#L1379" rel="noopener noreferrer"&gt;its constructor&lt;/a&gt; is easy to find. The most interesting aspect is how it initializes the &lt;code&gt;_registers&lt;/code&gt; member variable using a pointer to &lt;code&gt;unw_context_t&lt;/code&gt;. The &lt;a href="https://github.com/llvm/llvm-project/blob/4237ec343a7f0c0d3717972b14ae22ec10ff74cd/libunwind/src/Registers.hpp#L359" rel="noopener noreferrer"&gt;constructor is located nearby&lt;/a&gt;, and the type is defined in an earlier step.&lt;/p&gt;

&lt;p&gt;Note that the cursor moves through different stack frames using the &lt;code&gt;__unw_step&lt;/code&gt; function. This topic exceeds the scope of this article, so we'll leave it as homework for the most inquisitive minds.&lt;/p&gt;

&lt;h3&gt;
  
  
  Some info about the procedure in libunwind
&lt;/h3&gt;

&lt;p&gt;Here's the code that kicked off our investigation today:&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;_Unwind_Personality_Fn&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_handler_function&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;frameInfo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="c1"&gt;// ....&lt;/span&gt;
&lt;span class="n"&gt;_Unwind_Reason_Code&lt;/span&gt; &lt;span class="n"&gt;personalityResult&lt;/span&gt; &lt;span class="o"&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;p&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;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exception_object&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;exception_class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;exception_object&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;_Unwind_Context&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;cursor&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;Now that we know the cursor's origin, we can see where the &lt;code&gt;frameInfo&lt;/code&gt; variable comes from.&lt;/p&gt;

&lt;p&gt;In the code for both phases, we can see that this structure is populated by the &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/libunwind.cpp#L238" rel="noopener noreferrer"&gt;&lt;code&gt;__unw_get_proc_info&lt;/code&gt;&lt;/a&gt; function. It looks something 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;unw_proc_info_t&lt;/span&gt; &lt;span class="n"&gt;frameInfo&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;__unw_get_proc_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cursor&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;frameInfo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;UNW_ESUCCESS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside &lt;code&gt;__unw_get_proc_info&lt;/code&gt;, the pointer to &lt;code&gt;unw_cursor_t&lt;/code&gt; is cast to the pointer to &lt;code&gt;AbstractUnwindCursor&lt;/code&gt;, and then it calls the &lt;code&gt;getInfo&lt;/code&gt; member function. We already saw how an instance of a specific &lt;code&gt;UnwindCursor&lt;/code&gt; type is created inside the cursor. &lt;code&gt;AbstractUnwindCursor&lt;/code&gt; is a virtual interface to objects of this class.&lt;/p&gt;

&lt;p&gt;Inside the &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/UnwindCursor.hpp#L3297" rel="noopener noreferrer"&gt;&lt;code&gt;getInfo&lt;/code&gt;&lt;/a&gt; member function, the &lt;code&gt;unw_proc_info_t&lt;/code&gt; instance stored within the cursor class is copied into the variable we're looking for. But wait... I can't recall seeing anything written to that internal member variable. Moreover, I remember it being directly zeroed &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/UnwindCursor.hpp#L1386" rel="noopener noreferrer"&gt;in the constructor&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What did we miss?
&lt;/h3&gt;

&lt;p&gt;The address of our precious &lt;code&gt;handler&lt;/code&gt; can't be null. Besides, the address of some handler can't possibly appear in the registers. Let's face it, up until now, everything we've seen has been focused on preserving register states. I don't know about you, but I don't remember the System V ABI—or any other, for that matter—describing a separate register for some handler. So, that information is stored somewhere else.&lt;/p&gt;

&lt;p&gt;Let's look into this some more and return to the &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/libunwind.cpp#L91" rel="noopener noreferrer"&gt;&lt;code&gt;__unw_init_local&lt;/code&gt;&lt;/a&gt; function. We deliberately omitted the call to the &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/UnwindCursor.hpp#L2722" rel="noopener noreferrer"&gt;&lt;code&gt;setInfoBasedOnIPRegister&lt;/code&gt;&lt;/a&gt; function there. Its name suggests that this might be exactly what we need. Perhaps the value of the data member in question is set there, among the many conditional compilation directives.&lt;/p&gt;

&lt;p&gt;We have two options here: we can either figure out how binary files are parsed on GNU/Linux to find information for stack tracing, or we can just stop. Since this doesn't directly relate to the topic of this article, I think it's best to avoid getting bogged down in such details. Still, let's break down the general points, because that's exactly what makes &lt;em&gt;table-based&lt;/em&gt; exceptions, well, &lt;em&gt;table-based&lt;/em&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Summary N1
&lt;/h3&gt;

&lt;p&gt;Why don't we make an interim summary?&lt;/p&gt;

&lt;p&gt;Before moving down the stack, it's necessary to record the current processor state—the values of all its registers. To do this, we'll use &lt;code&gt;unw_context_t&lt;/code&gt;. It's populated using the &lt;code&gt;__unw_getcontext&lt;/code&gt; function, which is written in the assembly language. Its task is to simply copy the current register values into this structure. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;unw_cursor_t&lt;/code&gt; structure is used to navigate through stack frames. A cursor is an opaque pointer. In fact, it contains a hidden instance of the &lt;code&gt;UnwindCursor&lt;/code&gt; class. The cursor is created using the context directly in the memory buffer of the &lt;code&gt;unw_cursor_t&lt;/code&gt; structure. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;unw_proc_info_t&lt;/code&gt; structure is used to retrieve information about the function that created the stack frame we're interested in. The &lt;code&gt;__unw_get_proc_info&lt;/code&gt; function populates the structure. It takes our cursor and pulls details about the current function from its internal data (the &lt;code&gt;_info&lt;/code&gt; data member).&lt;/p&gt;

&lt;p&gt;The key question is this: if the cursor constructor simply zeroes everything, where does it get function-specific data, such as the address of the exception handler (i.e., the personality routine)?&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%2Fi4ijy1fi7l3jcm3buneb.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%2Fi4ijy1fi7l3jcm3buneb.png" alt="1360_LinuxExceptionTwo/image2.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ELF, DWARF, and other xenos species
&lt;/h2&gt;

&lt;p&gt;To get a better grasp of the issue, let's expand a bit the assembly code we obtained from our test example at the very beginning. Oh no, we won't be adding anything to the original C++ source code. Instead, we'll take a look at the complete version of this assembly code. It contains the code fragment directly related to our C++ source code, as well as various additional directives. I won't include the code in the article itself, as it's way too long. Let's look at some fragments below; the full code is available &lt;a href="https://godbolt.org/z/cnrz7KE6x" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The .cfi directives
&lt;/h3&gt;

&lt;p&gt;The code has become much longer due to the additional metadata. We'll focus on the &lt;code&gt;.cfi*&lt;/code&gt; family of directives that enable the debugger and profilers to traverse the stack, restore the frame state, and perform other tasks. &lt;/p&gt;

&lt;p&gt;They don't execute code, but instead create &lt;em&gt;unwind tables&lt;/em&gt;, also known as &lt;em&gt;exception frames&lt;/em&gt;. The tables aren't in the assembly file; the compiler creates them in the final binary. You can view them using, for example, the &lt;code&gt;readelf -w&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;Here's an example of running the 'readelf -w' main command:&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="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;readelf&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;
&lt;span class="n"&gt;Contents&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;eh_frame&lt;/span&gt; &lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;

&lt;span class="mo"&gt;00000000&lt;/span&gt; &lt;span class="mo"&gt;0000000000000014&lt;/span&gt; &lt;span class="mo"&gt;00000000&lt;/span&gt; &lt;span class="n"&gt;CIE&lt;/span&gt;
  &lt;span class="n"&gt;Version&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;Augmentation&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;          &lt;span class="s"&gt;"zR"&lt;/span&gt;
  &lt;span class="n"&gt;Code&lt;/span&gt; &lt;span class="n"&gt;alignment&lt;/span&gt; &lt;span class="n"&gt;factor&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;Data&lt;/span&gt; &lt;span class="n"&gt;alignment&lt;/span&gt; &lt;span class="n"&gt;factor&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;
  &lt;span class="n"&gt;Return&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
  &lt;span class="n"&gt;Augmentation&lt;/span&gt; &lt;span class="n"&gt;data&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;b&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_def_cfa&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;r7&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rsp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;ofs&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_offset&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;r16&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="n"&gt;cfa&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_nop&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_nop&lt;/span&gt;

&lt;span class="mo"&gt;0000001&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="mo"&gt;0000000000000014&lt;/span&gt; &lt;span class="mo"&gt;0000001&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="n"&gt;FDE&lt;/span&gt; &lt;span class="n"&gt;cie&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mo"&gt;00000000&lt;/span&gt;
&lt;span class="n"&gt;pc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mo"&gt;00000000000010&lt;/span&gt;&lt;span class="n"&gt;a0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;.00000000000010&lt;/span&gt;&lt;span class="n"&gt;c6&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_advance_loc&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="mo"&gt;00000000000010&lt;/span&gt;&lt;span class="n"&gt;a4&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_undefined&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;r16&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_nop&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_nop&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_nop&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_nop&lt;/span&gt;

&lt;span class="mo"&gt;00000030&lt;/span&gt; &lt;span class="mo"&gt;0000000000000024&lt;/span&gt; &lt;span class="mo"&gt;00000034&lt;/span&gt; &lt;span class="n"&gt;FDE&lt;/span&gt; &lt;span class="n"&gt;cie&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mo"&gt;00000000&lt;/span&gt;
&lt;span class="n"&gt;pc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0000000000001020..0000000000001090&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_def_cfa_offset&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_advance_loc&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="mo"&gt;0000000000001026&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_def_cfa_offset&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_advance_loc&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="mo"&gt;0000000000001030&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_def_cfa_expression&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_nop&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_nop&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_nop&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_nop&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They allow the stack unwinder to restore stack frame states using only the instruction pointer value. It looks suspiciously similar to the debugger information in debug builds, because that's exactly what it is. The debugger does pretty much the same thing. The table format is defined in the DWARF standard, which is why the exception-handling approach discussed here is sometimes referred to as &lt;em&gt;DWARF-based&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;These directives are all necessary for a program, such as a debugger, to retrieve information about the currently examined stack frame. This topic is beyond the scope of this article. There are three ways to learn more: read a &lt;a href="https://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html" rel="noopener noreferrer"&gt;brief note&lt;/a&gt; about the format of these tables and leave it at that, check out &lt;a href="https://maskray.me/blog/2020-11-08-stack-unwinding" rel="noopener noreferrer"&gt;this excellent introductory article&lt;/a&gt; on the topic, or dig into the &lt;a href="https://dwarfstd.org/doc/DWARF5.pdf" rel="noopener noreferrer"&gt;DWARF documentation&lt;/a&gt; (if you're a true rock and roller).&lt;/p&gt;

&lt;p&gt;However, we're interested in a few specific aspects. Take a look at the &lt;code&gt;foo&lt;/code&gt; function prologue (the one that catches the exception in our 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;foo&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;Lfunc_begin1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loc&lt;/span&gt;    &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;7&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;cfi_startproc&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cfi_personality&lt;/span&gt; &lt;span class="mi"&gt;155&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DW&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__gxx_personality_v0&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cfi_lsda&lt;/span&gt; &lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Lexception0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two directives deserve particular attention: &lt;code&gt;.cfi_personality&lt;/code&gt; and &lt;code&gt;.cfi_lsda&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Since we're working with LLVM, let's consult their &lt;a href="https://llvm.org/docs/ExceptionHandling.html" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;. There's some interesting content, including a link to &lt;a href="https://sourceware.org/binutils/docs/as/CFI-directives.html" rel="noopener noreferrer"&gt;other documentation&lt;/a&gt; that specifically describes the &lt;code&gt;.cfi&lt;/code&gt; directives we need. As the description states, the &lt;code&gt;.cfi_personality&lt;/code&gt; directive specifies where the stack unwinder retrieves the personality routine. Note that in our code, this instruction contains the &lt;code&gt;DW.ref.__gxx_personality_v0&lt;/code&gt; symbol. The origin of this symbol has remained a mystery to us since the first article.&lt;/p&gt;

&lt;p&gt;Take a look at the code at the very bottom of the assembly file:&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;DW&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__gxx_personality_v0&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="n"&gt;__gxx_personality_v0&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ident&lt;/span&gt;  &lt;span class="s"&gt;"clang version 21.1.0&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        .section        "&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GNU&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="s"&gt;","",@progbits&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        .addrsig&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        .addrsig_sym bar()&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        .addrsig_sym __cxa_allocate_exception&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        .addrsig_sym __cxa_throw&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        .addrsig_sym foo()&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        .addrsig_sym __gxx_personality_v0&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        .addrsig_sym __cxa_begin_catch&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        .addrsig_sym __cxa_end_catch&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        .addrsig_sym __clang_call_terminate&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        .addrsig_sym _ZSt9terminatev&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        .addrsig_sym _Unwind_Resume&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        .addrsig_sym _ZTIi&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        .section        .debug_line,"",@progbits&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The address of the &lt;code&gt;__gxx_personality_v0&lt;/code&gt; function is stored in memory. Next comes a section containing symbols that we've already encountered.&lt;/p&gt;

&lt;p&gt;The directive in &lt;code&gt;.cfi_lsda&lt;/code&gt; specifies the location of the &lt;em&gt;language-specific data area&lt;/em&gt;. What's this? Now look at the symbol located near the end of the &lt;code&gt;foo&lt;/code&gt; function:&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="nl"&gt;GCC_except_table1:&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Lexception0&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;byte&lt;/span&gt;   &lt;span class="mi"&gt;255&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;byte&lt;/span&gt;   &lt;span class="mi"&gt;155&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uleb128&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Lttbase0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Lttbaseref0&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Lttbaseref0&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;byte&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;uleb128&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Lcst_end0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Lcst_begin0&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;Good news—we've finally found this thing called &lt;em&gt;exception handling tables&lt;/em&gt;. More precisely, this is the &lt;em&gt;language-specific data area (lsda)&lt;/em&gt;, which contains the &lt;em&gt;exception handling tables&lt;/em&gt;. There are several of these tables, and we'll take a look at them a little later.&lt;/p&gt;

&lt;p&gt;Okay, we still don't know exactly how the personality routine and lsda work, but at least we've found where their symbols are defined. In the case of lsda, we also found its exact location.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reading binaries
&lt;/h3&gt;

&lt;p&gt;The way these two components—the personality-routines and lsda—work is simple: the first looks to the second to determine what to do with the exception in each stack frame it encounters. We'll see how it works a little later. For now, let's make sure that the C++ runtime actually reads addresses of the personality routines and lsda. To do this, we'll go back to the breakdown of the &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/UnwindCursor.hpp#L2722" rel="noopener noreferrer"&gt;&lt;code&gt;setInfoBasedOnIPRegister&lt;/code&gt;&lt;/a&gt; function.&lt;/p&gt;

&lt;p&gt;The code contained many conditional compilation directives depending on the runtime's stack unwinding technique. Since we now know that the method in question is DWARF-based, we can locate the relevant parts of this function. There are two of them: &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/UnwindCursor.hpp#L2814" rel="noopener noreferrer"&gt;one&lt;/a&gt; and &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/UnwindCursor.hpp#L2837" rel="noopener noreferrer"&gt;two&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let's stop here— describing how to read DWARF structures would make this article endless. The resources listed above should give you a general idea of the topic. Long story short, it all comes down to the &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/UnwindCursor.hpp#L1730" rel="noopener noreferrer"&gt;&lt;code&gt;getInfoFromFdeCie&lt;/code&gt;&lt;/a&gt; function. It actually populates the &lt;code&gt;_info&lt;/code&gt; data member using information obtained from the &lt;em&gt;unwind tables&lt;/em&gt;, including the addresses of the personality routine and lsda.&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary N2
&lt;/h3&gt;

&lt;p&gt;It seems like now's the time for a little summary. &lt;/p&gt;

&lt;p&gt;The compiler inserts special directives that begin with &lt;code&gt;.cfi_&lt;/code&gt; (Call Frame Information) when converting C++ code into assembly. The processor doesn't actually execute these directives—they instruct the linker to build unwinding tables from this data.&lt;/p&gt;

&lt;p&gt;We've already seen a few of them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;.cfi_personality&lt;/code&gt; specifies the address of the exception handler (the personality routine) for the function;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.cfi_lsda&lt;/code&gt; points to the Language Specific Data Area (LSDA)—function-specific metadata that tells the runtime how to handle an exception when it processes a particular stack frame.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After compilation, all &lt;code&gt;.cfi&lt;/code&gt; directives are converted into binary structures, which we can view using the &lt;code&gt;readelf -w&lt;/code&gt; command.  They contain &lt;code&gt;.eh_frame&lt;/code&gt; entries with general information on how to unwind the stack for each function.&lt;/p&gt;

&lt;p&gt;How exactly does the personality routine read the lsda, though?&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%2F5c9ubtcrdkqtc25rdo57.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%2F5c9ubtcrdkqtc25rdo57.png" alt="1360_LinuxExceptionTwo/image3.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The personality routine, lsda, and two types of unwinding
&lt;/h2&gt;

&lt;p&gt;The challenge with the personality routine is that it performs many similar actions in similar scenarios that still need to be distinguished from one another. Combine this with various ways to unwind the stack and exceptions that might occur in other languages, and the result is a Frankenstein's monster. Still, all these parts serve the same goal, and that's where we'll start.&lt;/p&gt;

&lt;p&gt;The personality routine parses the lsda to determine how to handle the exception within the context of a specific stack frame. In other words, it must know how to parse the stack in order to retrieve from memory the data contained in the lsda. Although this routine involves low-level work, it's conceptually quite high up in the Itanium ABI, at a level that defines language-specific functionality. &lt;/p&gt;

&lt;p&gt;In the previous article, we looked at an interface from the &lt;code&gt;_cxa*&lt;/code&gt; family responsible for exception allocation, throwing, and catching. This behavior applies only to the C++ language and isn't related to stack unwinding, which conceptually operates at a lower level. The personality routine is on the same level as the &lt;code&gt;_cxa*&lt;/code&gt; family, and it acts as a callback invoked by other subsystems during stack unwinding.&lt;/p&gt;

&lt;p&gt;There are two unwinding contexts where the personality routine is called: an exception throw and something else. The first one is initiated in the &lt;code&gt;_Unwind_RaiseException&lt;/code&gt; and &lt;code&gt;_Unwind_SjLj_RaiseException&lt;/code&gt; functions, while &lt;code&gt;_Unwind_ForcedUnwind&lt;/code&gt; is responsible for everything else (such as unwinding the stack when exiting a thread). An exception throw consists of two stages: finding the appropriate &lt;code&gt;catch&lt;/code&gt; block and cleaning up the stack. We covered all of this in the previous article.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/llvm/llvm-project/blob/bd0769ef869a1341e8122978e1eafc78c5f3d312/libunwind/include/unwind.h#L54" rel="noopener noreferrer"&gt;&lt;code&gt;_Unwind_Action&lt;/code&gt;&lt;/a&gt; defines the specific context. It shows that during the second phase of exception handling, the routine can do one of two things: either clean up the current frame or transfer control to a catch block identified during the first phase. It also includes a separate case for reaching the end of the stack during unwinding without an exception. &lt;/p&gt;

&lt;h3&gt;
  
  
  The personality routine algorithm
&lt;/h3&gt;

&lt;p&gt;Okay, let's take a look at the &lt;a href="https://github.com/llvm/llvm-project/blob/bd0769ef869a1341e8122978e1eafc78c5f3d312/libcxxabi/src/cxa_personality.cpp#L1029" rel="noopener noreferrer"&gt;code of this routine&lt;/a&gt;. We'll skip the details of parsing the lsda for now and try to grasp the general logic. For the sake of simplicity, we'll remove the conditional compilation that isn't relevant to our stack unwinding approach or platform.&lt;/p&gt;

&lt;p&gt;The simplest case occurs when, during the second phase, we reach the same frame that we marked in the first phase as having a valid &lt;code&gt;catch&lt;/code&gt; block.&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="n"&gt;actions&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_UA_CLEANUP_PHASE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;_UA_HANDLER_FRAME&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;native_exception&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Reload the results from the phase 1 cache.&lt;/span&gt;
    &lt;span class="n"&gt;__cxa_exception&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;exception_header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__cxa_exception&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;unwind_exception&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="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;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ttypeIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;exception_header&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;handlerSwitchValue&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;actionRecord&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;exception_header&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;actionRecord&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;languageSpecificData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;exception_header&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;languageSpecificData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;set_landing_pad&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;exception_header&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;catchTemp&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;adjustedPtr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;exception_header&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;adjustedPtr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;set_registers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unwind_exception&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;results&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;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ttypeIndex&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&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;span class="n"&gt;exception_header&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;catchTemp&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="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_URC_INSTALL_CONTEXT&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 this point, the routine retrieves the information it gathered during the previous phase and returns the &lt;code&gt;_URC_INSTALL_CONTEXT&lt;/code&gt; value. This tells &lt;a href="https://github.com/llvm/llvm-project/blob/bd0769ef869a1341e8122978e1eafc78c5f3d312/libunwind/src/UnwindLevel1.c#L212C1-L212C14" rel="noopener noreferrer"&gt;&lt;code&gt;unwind_phase2&lt;/code&gt;&lt;/a&gt; that it's time to move to the &lt;code&gt;catch&lt;/code&gt; block. The exact landing point comes from the cursor state &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/UnwindLevel1.c#L304" rel="noopener noreferrer"&gt;passed when calling the routine&lt;/a&gt; and set in the &lt;a href="https://github.com/llvm/llvm-project/blob/bd0769ef869a1341e8122978e1eafc78c5f3d312/libcxxabi/src/cxa_personality.cpp#L592" rel="noopener noreferrer"&gt;&lt;code&gt;set_registers&lt;/code&gt;&lt;/a&gt; function.&lt;/p&gt;

&lt;p&gt;In all other cases, that is, if we haven't reached the end of the exception throw's second phase, we need to parse the lsda to determine the next step:&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;scan_eh_tab&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;actions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;native_exception&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unwind_exception&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The following code is a bit unintuitive:&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="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reason&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;_URC_CONTINUE_UNWIND&lt;/span&gt; &lt;span class="o"&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;reason&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;_URC_FATAL_PHASE1_ERROR&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;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reason&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;actions&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;_UA_SEARCH_PHASE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reason&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;_URC_HANDLER_FOUND&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;native_exception&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;__cxa_exception&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;exc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__cxa_exception&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;unwind_exception&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="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;exc&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;handlerSwitchValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;static_cast&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&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;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ttypeIndex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;actionRecord&lt;/span&gt; &lt;span class="o"&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;actionRecord&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;languageSpecificData&lt;/span&gt; &lt;span class="o"&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;languageSpecificData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;get_landing_pad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;catchTemp&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;exc&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;adjustedPtr&lt;/span&gt; &lt;span class="o"&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;adjustedPtr&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;_URC_HANDLER_FOUND&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;code&gt;_URC_CONTINUE_UNWIND&lt;/code&gt; can be set in either the first or second phase. The first one is clear: a handler hasn't been found at that point. In the second phase, this value is set if the stack in question contains neither &lt;code&gt;catch&lt;/code&gt; blocks nor automatic variables whose destructors should be called when unwinding the stack.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;_URC_FATAL_PHASE1_ERROR&lt;/code&gt; is set when the parser finds something in lsda that shouldn't be there. This indicates an error.&lt;/p&gt;

&lt;p&gt;Otherwise, there's only one thing left to do in the first phase—celebrate finding the right handler! For native C++ exceptions, we store the relevant information for later (we saw it being used toward the end of the second phase earlier). For foreign exceptions, we simply report finding the handler. In both cases, the routine returns &lt;code&gt;_URC_HANDLER_FOUND&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;At this point, only one option remains: we're in the second phase and need to perform some action in the current stack frame:&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;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;actions&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;_UA_CLEANUP_PHASE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reason&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;_URC_HANDLER_FOUND&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What can it be? Given that we'd enter the valid &lt;code&gt;catch&lt;/code&gt; block right at the beginning of the function, we have two options: to either call stack variable destructors, or handle &lt;a href="https://en.cppreference.com/w/cpp/language/except_spec.html" rel="noopener noreferrer"&gt;exception specifications&lt;/a&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;set_registers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unwind_exception&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;results&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;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ttypeIndex&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&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;span class="n"&gt;__cxa_exception&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;exception_header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__cxa_exception&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;unwind_exception&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="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;exception_header&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;catchTemp&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="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_URC_INSTALL_CONTEXT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last line is all we need here. The &lt;code&gt;_URC_INSTALL_CONTEXT&lt;/code&gt; value instructs the runtime to transfer control to the code fragment the routine found. This is a &lt;em&gt;landing pad&lt;/em&gt;, which is a block of code that either handles an exception or an exception specification, or it calls destructors.&lt;/p&gt;

&lt;h3&gt;
  
  
  The lsda structure
&lt;/h3&gt;

&lt;p&gt;The lsda is parsed in LLVM within the &lt;a href="https://github.com/llvm/llvm-project/blob/bd0769ef869a1341e8122978e1eafc78c5f3d312/libcxxabi/src/cxa_personality.cpp#L645" rel="noopener noreferrer"&gt;&lt;code&gt;scan_eh_tab&lt;/code&gt;&lt;/a&gt; function. Analyzing how it works would be interesting, but instead, explaining what exactly this lsda contains—with varying degrees of clarity—seems more useful.&lt;/p&gt;

&lt;p&gt;As we previously learned, the lsda includes exception handling tables. The name kind of hints that there are multiple of those. The &lt;a href="https://itanium-cxx-abi.github.io/cxx-abi/exceptions.pdf" rel="noopener noreferrer"&gt;specification does confirm&lt;/a&gt; this.&lt;/p&gt;

&lt;p&gt;The first one is called the &lt;em&gt;call sites table&lt;/em&gt;. It's a list of entries containing pointers to the start and end of an instruction sequence containing the instruction from which the exception was thrown. With the address of this instruction (the unwinder restores it from the DWARF tables we discussed above), we can understand which entry to use. The call site itself is a code snippet located either inside or outside the &lt;code&gt;try&lt;/code&gt; block. It's kind of a critical section where specific actions happen during stack unwinding. The list of possible actions follows the call sites table, and the required action is identified by an index that is stored alongside pointers to the start and end of a specific call site.&lt;/p&gt;

&lt;p&gt;Right after the call site table comes the &lt;em&gt;action table&lt;/em&gt;, which is a list of actions associated with a particular call site. Although it's called a "table," it's actually a linked list. In addition to a pointer to the next node, each element contains a &lt;em&gt;type index&lt;/em&gt;, which is a multipurpose data member of an integer type. If it's zero, then destructors are called in the current stack frame. Control must be passed to the code that contains calls generated by the compiler. If it's greater than zero, then we're dealing with the &lt;code&gt;catch&lt;/code&gt; block, and it's necessary to check whether the &lt;code&gt;catch&lt;/code&gt; block type matches the exception type. In this case, the number acts as an index to a table of types supported by the &lt;code&gt;catch&lt;/code&gt; blocks of this frame (that table follows the current one). If the index is negative, then we're dealing with an exception specification, and it's necessary to determine whether the function can throw an exception of that type.&lt;/p&gt;

&lt;p&gt;Following the action table is the &lt;em&gt;type table&lt;/em&gt;, which contains references to the &lt;code&gt;std::type_info&lt;/code&gt; objects for the types supported by the &lt;code&gt;catch&lt;/code&gt; blocks of the current frame. This table is indexed by the positive indices contained in the nodes of the action table linked list.&lt;/p&gt;

&lt;p&gt;Somewhere nearby—depending on the implementation—is a list of references to the &lt;code&gt;std::type_info&lt;/code&gt; types listed in the exception specification. If you're using older standards that allow such specifications, this is where the runtime handles unsupported types. In this case, the handler logic works in reverse: &lt;a href="https://github.com/llvm/llvm-project/blob/bd0769ef869a1341e8122978e1eafc78c5f3d312/libcxxabi/src/cxa_personality.cpp#L1282" rel="noopener noreferrer"&gt;&lt;code&gt;__cxa_call_unexpected&lt;/code&gt;&lt;/a&gt; is called when an exception lands in the generated code after violating the specification. That function ultimately behaves similarly to the deprecated &lt;a href="https://en.cppreference.com/w/cpp/error/unexpected.html" rel="noopener noreferrer"&gt;&lt;code&gt;std::unexpected&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The structure of this mess looks something 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="o"&gt;========================&lt;/span&gt;
&lt;span class="n"&gt;Lsda&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt;
&lt;span class="n"&gt;LPStart&lt;/span&gt; &lt;span class="n"&gt;Encoding&lt;/span&gt;
&lt;span class="n"&gt;LPStart&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;TType&lt;/span&gt; &lt;span class="n"&gt;Encoding&lt;/span&gt;
&lt;span class="n"&gt;TType&lt;/span&gt; &lt;span class="n"&gt;Offset&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Call&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Site&lt;/span&gt; &lt;span class="n"&gt;Encoding&lt;/span&gt;
&lt;span class="n"&gt;Call&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Site&lt;/span&gt; &lt;span class="n"&gt;Table&lt;/span&gt; &lt;span class="n"&gt;Length&lt;/span&gt;
&lt;span class="o"&gt;========================&lt;/span&gt;
&lt;span class="n"&gt;Call&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Site&lt;/span&gt; &lt;span class="n"&gt;Table&lt;/span&gt;
&lt;span class="o"&gt;------------------------&lt;/span&gt;
&lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;site&lt;/span&gt;
&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;site&lt;/span&gt;
&lt;span class="n"&gt;landingPad&lt;/span&gt; &lt;span class="p"&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;offset&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;landingPad&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;actionEntry&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;based&lt;/span&gt; &lt;span class="n"&gt;offset&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="n"&gt;start&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;site&lt;/span&gt;
&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;site&lt;/span&gt;
&lt;span class="n"&gt;landingPad&lt;/span&gt; &lt;span class="p"&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;offset&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;landingPad&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;actionEntry&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;based&lt;/span&gt; &lt;span class="n"&gt;offset&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="n"&gt;Action&lt;/span&gt; &lt;span class="n"&gt;Table&lt;/span&gt;
&lt;span class="o"&gt;------------------------&lt;/span&gt;
&lt;span class="n"&gt;ttypeIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="n"&gt;nextOffset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt; 
&lt;span class="o"&gt;------------------------&lt;/span&gt;
&lt;span class="o"&gt;------------------------&lt;/span&gt;
&lt;span class="n"&gt;ttypeIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="n"&gt;nextOffset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt; 
&lt;span class="o"&gt;------------------------&lt;/span&gt;
&lt;span class="o"&gt;------------------------&lt;/span&gt;
&lt;span class="n"&gt;ttypeIndex&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;nextOffset&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="o"&gt;========================&lt;/span&gt;
&lt;span class="n"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;Table&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RTTI&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;------------------------&lt;/span&gt;
&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="err"&gt;──&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;typeinfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;float&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="n"&gt;index&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="err"&gt;──&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;typeinfo&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="o"&gt;------------------------&lt;/span&gt;
&lt;span class="o"&gt;------------------------&lt;/span&gt;
&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="err"&gt;──&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;typeinfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Summary N3
&lt;/h3&gt;

&lt;p&gt;That's the way the ball bounces. Let's summarize!&lt;/p&gt;

&lt;p&gt;The personality routine can parse the lsda. The lsda contains language-specific information about what should happen in a given stack frame when an exception is thrown. The lsda is generated by the compiler and appended to the function body.&lt;/p&gt;

&lt;p&gt;The personality routine is called from the &lt;code&gt;_Unwind*&lt;/code&gt; family of functions, which are stack unwinding drivers. These functions form a layer independent of any programming language. In other words, a routine is a callback that logically belongs to a language-specific layer.&lt;/p&gt;

&lt;p&gt;We also learned about the "landing pad" concept. This is essentially a generalization over the &lt;code&gt;catch&lt;/code&gt; block, which can handle exception specifications and destructor calls in addition to the exceptions.&lt;/p&gt;

&lt;p&gt;So, how does this landing pad actually work?&lt;/p&gt;

&lt;h2&gt;
  
  
  The last mile and landing pad
&lt;/h2&gt;

&lt;p&gt;We've slightly modified the code for clarity:&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="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;throw&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="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&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="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;666&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;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&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;bar&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;float&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="mi"&gt;69&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;catch&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="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(...)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//skiped intentionally&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;666&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;foo&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 assembly code is below. The &lt;a href="https://godbolt.org/z/7sfqczxss" rel="noopener noreferrer"&gt;link leads&lt;/a&gt; to the same file, but it has additional compiler directives.&lt;/p&gt;

&lt;p&gt;Assembly 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="n"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;push&lt;/span&gt;    &lt;span class="n"&gt;rbp&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rsp&lt;/span&gt;
        &lt;span class="n"&gt;sub&lt;/span&gt;     &lt;span class="n"&gt;rsp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;ecx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
        &lt;span class="n"&gt;cdq&lt;/span&gt;
        &lt;span class="n"&gt;idiv&lt;/span&gt;    &lt;span class="n"&gt;ecx&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&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="mi"&gt;0&lt;/span&gt;
        &lt;span class="n"&gt;cmp&lt;/span&gt;     &lt;span class="n"&gt;edx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&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;LBB0_2&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;edi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_allocate_exception&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&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="n"&gt;rdi&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&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="mi"&gt;1&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rdi&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;mov&lt;/span&gt;     &lt;span class="n"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rip&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;typeinfo&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;GOTPCREL&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;xor&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;edx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_throw&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;jmp&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB0_8&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB0_2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;jmp&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB0_3&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB0_3&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4294966630&lt;/span&gt;
        &lt;span class="n"&gt;add&lt;/span&gt;     &lt;span class="n"&gt;rsp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;
        &lt;span class="n"&gt;pop&lt;/span&gt;     &lt;span class="n"&gt;rbp&lt;/span&gt;
        &lt;span class="n"&gt;ret&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rcx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;edx&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;rcx&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;cmp&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="n"&gt;jge&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB0_7&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_call_unexpected&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB0_7&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;_Unwind_Resume&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB0_8&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;

&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;push&lt;/span&gt;    &lt;span class="n"&gt;rbp&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rsp&lt;/span&gt;
        &lt;span class="n"&gt;sub&lt;/span&gt;     &lt;span class="n"&gt;rsp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;48&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&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;eax&lt;/span&gt;
        &lt;span class="n"&gt;jmp&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_1&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&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;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&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="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;jmp&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_9&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rcx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;edx&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&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;rcx&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;ecx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
        &lt;span class="n"&gt;cmp&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ecx&lt;/span&gt;
        &lt;span class="n"&gt;jne&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_5&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&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;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_begin_catch&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;movss&lt;/span&gt;   &lt;span class="n"&gt;xmm0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;movss&lt;/span&gt;   &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;xmm0&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&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="mi"&gt;69&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_end_catch&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;jmp&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_9&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_5&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;ecx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
        &lt;span class="n"&gt;cmp&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ecx&lt;/span&gt;
        &lt;span class="n"&gt;jne&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_7&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&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;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_begin_catch&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&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="mi"&gt;42&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_end_catch&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;jmp&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_9&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_7&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&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;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_begin_catch&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_end_catch&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&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="mi"&gt;666&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_9&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&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="n"&gt;add&lt;/span&gt;     &lt;span class="n"&gt;rsp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;48&lt;/span&gt;
        &lt;span class="n"&gt;pop&lt;/span&gt;     &lt;span class="n"&gt;rbp&lt;/span&gt;
        &lt;span class="n"&gt;ret&lt;/span&gt;

&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;push&lt;/span&gt;    &lt;span class="n"&gt;rbp&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rsp&lt;/span&gt;
        &lt;span class="n"&gt;sub&lt;/span&gt;     &lt;span class="n"&gt;rsp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&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="mi"&gt;0&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;add&lt;/span&gt;     &lt;span class="n"&gt;rsp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
        &lt;span class="n"&gt;pop&lt;/span&gt;     &lt;span class="n"&gt;rbp&lt;/span&gt;
        &lt;span class="n"&gt;ret&lt;/span&gt;

&lt;span class="n"&gt;DW&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__gxx_personality_v0&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="n"&gt;__gxx_personality_v0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, let's look at this little example with the &lt;code&gt;bar&lt;/code&gt; function:&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;LBB0_3&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4294966630&lt;/span&gt;
        &lt;span class="n"&gt;add&lt;/span&gt;     &lt;span class="n"&gt;rsp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;
        &lt;span class="n"&gt;pop&lt;/span&gt;     &lt;span class="n"&gt;rbp&lt;/span&gt;
        &lt;span class="n"&gt;ret&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rcx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;edx&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;rcx&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;cmp&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="n"&gt;jge&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB0_7&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_call_unexpected&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's interesting because it shows how exception specifications are handled. If the function throws an exception of a type not listed in its specification, the personality routine will read the lsda and instruct the unwinder to transfer control to this point. Calling &lt;code&gt;__cxa_call_unexpected&lt;/code&gt; is usually something that your program won't survive. &lt;/p&gt;

&lt;p&gt;Another interesting detail is in the &lt;code&gt;foo&lt;/code&gt; function. It handles the selection of the specific &lt;code&gt;catch&lt;/code&gt; block that processes the exception. The lsda provides the runtime with a pointer to a landing pad. However, that landing pad represents a &lt;em&gt;handler in general&lt;/em&gt; rather than a specific one. With &lt;code&gt;catch&lt;/code&gt; blocks, it points to the start of the entire &lt;code&gt;catch&lt;/code&gt; block section that follows a given &lt;code&gt;try&lt;/code&gt; block, rather than to a specific handler.&lt;/p&gt;

&lt;p&gt;Let's take, for example, an exception handler for the &lt;code&gt;int&lt;/code&gt; type:&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;LBB1_5&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;ecx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
        &lt;span class="n"&gt;cmp&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ecx&lt;/span&gt;
        &lt;span class="n"&gt;jne&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_7&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&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;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_begin_catch&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&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="mi"&gt;42&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_end_catch&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;jmp&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_9&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;LBB1_9&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&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="n"&gt;add&lt;/span&gt;     &lt;span class="n"&gt;rsp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;48&lt;/span&gt;
        &lt;span class="n"&gt;pop&lt;/span&gt;     &lt;span class="n"&gt;rbp&lt;/span&gt;
        &lt;span class="n"&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In addition to the usual things like calling &lt;code&gt;__cxa_begin_catch&lt;/code&gt; and &lt;code&gt;__cxa_end_catch&lt;/code&gt;, we can see some code that looks strange at first glance:&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;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;ecx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
        &lt;span class="n"&gt;cmp&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ecx&lt;/span&gt;
        &lt;span class="n"&gt;jne&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_7&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this fragment, a conditional jump occurs if something isn't equal to &lt;code&gt;2&lt;/code&gt;. &lt;code&gt;2&lt;/code&gt; of what? Why not &lt;code&gt;3&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;Think back to how we discussed tables within the lsda earlier. It contained a type table indexed by numbers found in entries of the action table. In this assembly code, &lt;code&gt;2&lt;/code&gt; is an index that the runtime &lt;a href="https://github.com/llvm/llvm-project/blob/bd0769ef869a1341e8122978e1eafc78c5f3d312/libcxxabi/src/cxa_personality.cpp#L1080" rel="noopener noreferrer"&gt;kindly stored&lt;/a&gt; in the &lt;code&gt;__cxa_exception&lt;/code&gt; structure of the thrown exception when calling the personality routine. If the program had thrown a different exception type that still matched one of the available &lt;code&gt;catch&lt;/code&gt; blocks, the runtime would've stored a different index to identify the correct type.&lt;/p&gt;

&lt;p&gt;That's it—it wasn't so bad after all! There isn't much to summarize here since this part doesn't introduce many new concepts.&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%2F8gzv0vzplj8sz9ensqgc.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%2F8gzv0vzplj8sz9ensqgc.png" alt="1360_LinuxExceptionTwo/image4.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Is this the end?
&lt;/h2&gt;

&lt;p&gt;Dear friends, if you're reading this, I want you to know that you're real heroes, and I admire you. Getting through all of this wasn't easy. I hope it was worth the effort, and you learned something cool—or at least something new—along the way!&lt;/p&gt;

&lt;p&gt;One question remains unanswered: how do exceptions over the &lt;code&gt;setjmp&lt;/code&gt;/ &lt;code&gt;longjmp&lt;/code&gt; mechanism work? That's a great reason to revisit the topic in the future!&lt;/p&gt;

&lt;p&gt;I'd love to read your thoughts in the comments—hope to see you there!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;El Psy Kongroo&lt;/em&gt;.&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>programming</category>
      <category>linux</category>
      <category>assembly</category>
    </item>
    <item>
      <title>"Please press button for assistance"</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Tue, 31 Mar 2026 06:28:00 +0000</pubDate>
      <link>https://forem.com/pvsdev/please-press-button-for-assistance-27p7</link>
      <guid>https://forem.com/pvsdev/please-press-button-for-assistance-27p7</guid>
      <description>&lt;p&gt;Back when I joined PVS-Studio five years ago, my ex-colleague (who pretty much taught me how to code) wrote an article on tech support and how to avoid burning out. Over the past few years, our support team has gone through significant changes, so it's time to update things.&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%2Fmo2ve52quqph6dpqp004.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%2Fmo2ve52quqph6dpqp004.png" alt="1359_press_here/image1.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm a customer support manager, so that's partly my job—and today I'll tell you about how we do things. Next, I'll show how the support team is currently working in PVS-Studio. Wishing you all the best and lots of positive vibes. But remember: if something goes wrong, &lt;a href="https://pvs-studio.com/en/about-feedback/" rel="noopener noreferrer"&gt;please click here for assistance&lt;/a&gt;...&lt;/p&gt;

&lt;h2&gt;
  
  
  Service structure
&lt;/h2&gt;

&lt;p&gt;I've been in PVS-Studio tech support for four years now. Back when I started, our developers handled all technical support themselves, but today, our support service has grown like a snowball honestly, I wouldn't mind being under that snowball myself.&lt;/p&gt;

&lt;p&gt;Over the years, we've gradually enhanced the quality of the support service and automated certain aspects of it. Now we have much greater control over our service operations and our own staff. Now I'll explain how developing in-house tools and making the most of our support team's experience has helped us raise the quality bar.&lt;/p&gt;

&lt;p&gt;The old model, where only developers provided support to users, worked as long as the workload wasn't too high. But the analyzer is growing, diagnostic rules are being developed, and integrations are being added. Even in the old, slightly simpler mode, it wasn't very handy. As the analyzer continued to evolve, there was a need to expand and automate the support pipeline. &lt;/p&gt;

&lt;p&gt;You can see the difference between how things used to be and what we've managed to put together so far in the tables below. Tsss... It's a little secret, but you'll get a sneak peek into how we work behind the scenes :) &lt;/p&gt;

&lt;p&gt;Look at support departments:&lt;/p&gt;

&lt;p&gt;Previously (pre-2021)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sales&lt;/strong&gt;: handles the evaluation period and initial non-technical support without getting into technical details, and handles partnership requests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Development departments&lt;/strong&gt;: handles all technical requests.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Currently (since 2024)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sales&lt;/strong&gt;: handles partnership opportunities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SalesDev&lt;/strong&gt;: handles evaluation period and first-line support.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Technical Support&lt;/strong&gt;: handles technical requests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Development departments&lt;/strong&gt;: handles specific technical requests.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I work in the SalesDev department and provide assistance when customers evaluate our tools. Plus, I handle the first-line support for resolving simple technical and advisory requests. If you're one of our clients, we might have even exchanged emails :) I also lead a project to expand our support services. We develop new tools, document processes, analyze technical support statistics, and identify areas for improvement.&lt;/p&gt;

&lt;p&gt;Looking at the numbers, splitting responsibilities across departments has been very helpful in distributing the workload across our development teams. The technical support department was established in late 2024, and in 2025, they already sent 1,119 emails.&lt;/p&gt;

&lt;p&gt;On top of my main duties, over the past four years my manager, colleagues from the technical departments, and I have rolled out a bunch of tech support projects, which you can see in the table listing the tools we've implemented along the way. &lt;/p&gt;

&lt;p&gt;The tools we use for support:&lt;/p&gt;

&lt;p&gt;Previously (pre-2021)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scenario flowcharts.&lt;/li&gt;
&lt;li&gt;Team stats, ticket handling time, etc.&lt;/li&gt;
&lt;li&gt;A third-party helpdesk where it was difficult to implement internal customizations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Currently (since 2024)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Our in-house helpdesk, where we can customize as we want (header, message body, email editing, comments, email threads, etc.)&lt;/li&gt;
&lt;li&gt;Communication tags: managerial, technical, etc.&lt;/li&gt;
&lt;li&gt;Technical closure statuses for conversations.&lt;/li&gt;
&lt;li&gt;Defined processes and areas of responsibility.&lt;/li&gt;
&lt;li&gt;Technical solutions database for the analyzer.&lt;/li&gt;
&lt;li&gt;Checklists for clarifying environments in specific cases.&lt;/li&gt;
&lt;li&gt;Updating the feedback page with templates based on the request.&lt;/li&gt;
&lt;li&gt;Scenario flowcharts.&lt;/li&gt;
&lt;li&gt;Built-in templates that employees create themselves.&lt;/li&gt;
&lt;li&gt;Team stats, ticket handling time, etc.&lt;/li&gt;
&lt;li&gt;Statistics on recurring patterns in conversations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the part I can actually show—the tools that make our support tick. Of course, people come first, but the numbers speak for themselves.&lt;/p&gt;

&lt;p&gt;For 2025, the the median ticket resolution time dropped by six days (from 19 to 13) and reduced our response time almost threefold. The current average response time is around 9 hours.&lt;/p&gt;

&lt;p&gt;Wishing everyone all the best, smooth processes, and lots of love—and once again, if something goes wrong, &lt;a href="https://pvs-studio.com/en/about-feedback/" rel="noopener noreferrer"&gt;please press here for assistance&lt;/a&gt;...&lt;/p&gt;

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

&lt;p&gt;Over the past five years, support for PVS-Studio has undergone many changes. All of this is for the benefit of our clients and employees. We've implemented some really useful tools, and now we're better able to understand users' needs and challenges, analyze our mistakes, and handle technical support requests. Our human resources are organized more effectively, with new departments each responsible for their own area of support and service.&lt;/p&gt;

&lt;p&gt;Support matters. In many cases, it's a key factor in whether a customer decides to use the tool regularly or purchase a license. &lt;/p&gt;

&lt;p&gt;This work has yielded significant results, as evidenced by our internal statistics. That's why support is awesome. And of course, we welcome your feedback!&lt;/p&gt;

&lt;p&gt;Wishing everyone peace, love, great articles, and successful projects—and once again (last time, I swear), if something goes wrong, &lt;a href="https://pvs-studio.com/en/about-feedback/" rel="noopener noreferrer"&gt;please press here for assistance&lt;/a&gt;...&lt;/p&gt;

</description>
      <category>career</category>
      <category>management</category>
      <category>mentalhealth</category>
      <category>workplace</category>
    </item>
    <item>
      <title>Get started with PVS-Studio static analyzer</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Fri, 27 Mar 2026 14:04:48 +0000</pubDate>
      <link>https://forem.com/pvsdev/get-started-with-pvs-studio-static-analyzer-4dlj</link>
      <guid>https://forem.com/pvsdev/get-started-with-pvs-studio-static-analyzer-4dlj</guid>
      <description>&lt;p&gt;PVS-Studio static analyzer is a tool for detecting code errors throughout the entire project lifecycle. In this article, you can meet the key analyzer features, common usage scenarios, and analysis options, and learn everything you need to get started. &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%2F3yaumgfu8odp6j4i9msf.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%2F3yaumgfu8odp6j4i9msf.png" alt=" " width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is PVS-Studio?
&lt;/h2&gt;

&lt;p&gt;PVS-Studio is a SAST tool that identifies potential errors and vulnerabilities in the source code of C, C++, C#, and Java projects. It's a B2B solution trusted by many development teams and companies around the world.&lt;/p&gt;

&lt;p&gt;The analyzer runs on Windows, Linux, and macOS, offering several usage and integration scenarios with various tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  Usage scenarios of static analysis
&lt;/h2&gt;

&lt;p&gt;PVS-Studio offers multiple ways to integrate static analysis into your workflow. It can be arranged as an IDE plugin, as well as an automated server testing tool. You can choose the approach that fits your workflow best—or combine all options to fully protect your code by integrating the analyzer at every developing stage. &lt;/p&gt;

&lt;h3&gt;
  
  
  On-premise analysis
&lt;/h3&gt;

&lt;p&gt;One of the practical ways to use the analyzer is to run it locally on developers' machines, either via the IDE plugin or the console version.&lt;/p&gt;

&lt;p&gt;This is also the most versatile approach, covering a wide range of environments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/docs/#ID2C86D8E9F3" rel="noopener noreferrer"&gt;Windows&lt;/a&gt;, &lt;a href="https://pvs-studio.com/en/docs/#ID0EB51357F9" rel="noopener noreferrer"&gt;Linux, and macOS&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/docs/#ID07C7EEF9C1" rel="noopener noreferrer"&gt;platform-independent launching methods&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/docs/#ID581D6381F3" rel="noopener noreferrer"&gt;IDEs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/docs/#IDBBB7F39D08" rel="noopener noreferrer"&gt;build systems&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/docs/#ID3B8887201D" rel="noopener noreferrer"&gt;game engines&lt;/a&gt; (PVS-Studio can analyze game projects).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This scenario allows developers to catch errors early and efficiently, right as the team is working on a new functionality or refining an existing one, enabling make quick code changes.&lt;/p&gt;

&lt;p&gt;However, it's worth combining multiple options to supply your pipeline with advanced security. For example, to prevent defects from entering version control systems (VCS), it'd be better to have a second-level protection: regular static analysis on the build server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Regular static analysis
&lt;/h3&gt;

&lt;p&gt;The best approach is to implement a two-level source code verification system both on premise and on server. The earlier an issue is detected, the lower the cost and complexity of fixing it. We would also recommend using &lt;a href="https://pvs-studio.com/en/docs/manual/0055/#modified_files" rel="noopener noreferrer"&gt;incremental analysis&lt;/a&gt; to automatically analyze only modified code after a build. This enables optimize and enhance performance the CI pipeline.&lt;/p&gt;

&lt;p&gt;Regular analysis for pull requests significantly streamlines the code review process. Even if errors get into VCS, they can be quickly spotted and fixed, potentially saving time, money, and the product's reputation.&lt;/p&gt;

&lt;p&gt;Early detection is one of the key static analysis benefits along its regular usage. Running analysis only once, for example, before a release, can lead to several problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Increased time required to review and mark up warnings&lt;/li&gt;
&lt;li&gt;Reduced analysis quality (the more warnings reviewed at once, the easier it's to miss important issues)&lt;/li&gt;
&lt;li&gt;More complex bug fixing (long periods between introducing and detecting an issue can force developers to spend time to familiarize with the context)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more details about the regular use of PVS-Studio, CI integration, and configuration recommendations, please refer to this &lt;a href="https://pvs-studio.com/en/docs/#ID07E414F700" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In addition to on-premise infrastructure, you can always configure analysis in cloud-based CI services. PVS-Studio integrates with most of the prominent cloud-based CI systems. You can find the complete list and setup instructions on this &lt;a href="https://pvs-studio.com/en/docs/?ysclid=mkxq6jhosz655884854#IDF1BF21914C" rel="noopener noreferrer"&gt;page&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;/strong&gt; PVS-Studio can analyze commits and branch merging (pull/merge requests). In this mode, only files modified relative to the current branch state are analyzed. This reduces analysis time and facilitates result review. More details are provided in the &lt;a href="https://pvs-studio.com/en/docs/manual/0055/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Server-side analysis
&lt;/h3&gt;

&lt;p&gt;Project analysis can be integrated into nightly builds to generate a detailed report on the codebase state each day. Regular analyzer feedback on detected issues can help quickly fix the problematic code.&lt;/p&gt;

&lt;p&gt;A key scenario characteristic is that the analyzer operates with the full project context. This increases effectiveness through intermodular analysis and detects issues in different program components.&lt;/p&gt;

&lt;p&gt;For example, a potential defect may be located in one file (e.g., a missing &lt;code&gt;null&lt;/code&gt; check) while its consequences appear in another program segment (e.g., a &lt;code&gt;NullReferenceException&lt;/code&gt; occurs when the object is accessed).&lt;/p&gt;

&lt;p&gt;To further improve efficiency, analysis results can be integrated with code quality management tools (web dashboards). These tools enhance interaction with reports without requiring changes to the existing development pipeline and provide additional capabilities such as analysis result visualization, report aggregation, issue tracking and resolution management, etc.&lt;/p&gt;

&lt;p&gt;The full list of supported tools and integration instructions is available in the &lt;a href="https://pvs-studio.com/en/docs/#ID0634466DF2" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Supported standards
&lt;/h2&gt;

&lt;p&gt;PVS-Studio is a SAST (&lt;a href="https://pvs-studio.com/en/blog/terms/6631/" rel="noopener noreferrer"&gt;Static Application Security Testing&lt;/a&gt;) solution that searches for security defects and helps refine overall code security.&lt;/p&gt;

&lt;h3&gt;
  
  
  Code reliability
&lt;/h3&gt;

&lt;p&gt;Code reliability is critical in industries where software defects can have severe consequences, such as aerospace, medical, and engineering. Errors in applications with high-reliability requirements can lead to millions of dollars in losses or even endanger human lives.&lt;/p&gt;

&lt;p&gt;To write reliable code, developers adhere to special coding standards, such as MISRA C, MISRA C++, and AUTOSAR Coding Guidelines.&lt;/p&gt;

&lt;p&gt;PVS-Studio identifies the code that doesn't comply with these standards. To see the full list of diagnostic rules mapped for the standards, please refer to the following documentation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/pvs-studio/sast/misra/" rel="noopener noreferrer"&gt;MISRA C and MISRA C++ Coding Standards&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/pvs-studio/sast/autosar/" rel="noopener noreferrer"&gt;AUTOSAR C++14 Coding Guidelines&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Code security
&lt;/h3&gt;

&lt;p&gt;Secure code is more resilient to various types of cyberattacks, such as &lt;a href="https://pvs-studio.com/en/blog/terms/6507/" rel="noopener noreferrer"&gt;SQL injections&lt;/a&gt;, &lt;a href="https://pvs-studio.com/en/blog/terms/6545/" rel="noopener noreferrer"&gt;XEE&lt;/a&gt;, &lt;a href="https://pvs-studio.com/en/blog/terms/6546/" rel="noopener noreferrer"&gt;XXE&lt;/a&gt;, and others. Thus, code security is especially critical in applications that handle user-sensitive data (banking software, web applications, etc.).&lt;/p&gt;

&lt;p&gt;To ensure applications are secure, development teams implement &lt;a href="https://pvs-studio.com/en/blog/terms/6733/" rel="noopener noreferrer"&gt;a secure software development lifecycle&lt;/a&gt; (SSDLC). One of its stages is to search for security issues using SAST (&lt;a href="https://pvs-studio.com/en/blog/terms/6631/" rel="noopener noreferrer"&gt;Static Application Security Testing)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Specialized standards are used to ensure secure code development. PVS-Studio maps its diagnostic rules to industry-recognized security standards and vulnerability lists (CWE), including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/pvs-studio/sast/cwe/" rel="noopener noreferrer"&gt;Common Weakness Enumeration (CWE)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/pvs-studio/sast/owasp/" rel="noopener noreferrer"&gt;OWASP ASVS (Application Security Verification Standard)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/pvs-studio/sast/cert/" rel="noopener noreferrer"&gt;SEI CERT Coding Standards&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Among all security flaws, the most dangerous and common ones are highlighted. Discover how PVS-Studio helps mitigate these risks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/pvs-studio/sast/owasptopten/" rel="noopener noreferrer"&gt;OWASP Top 10 Web Application Security Risks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/pvs-studio/sast/cwetop25/" rel="noopener noreferrer"&gt;CWE Top 25 Most Dangerous Software Weaknesses&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Choosing a PVS-Studio license
&lt;/h2&gt;

&lt;p&gt;Before getting started, we recommend reviewing the available PVS-Studio license options and choosing the one that best fits your team.&lt;/p&gt;

&lt;p&gt;PVS-Studio is primarily tool for development teams, so we do not provide single-user licenses. Licenses are packaged according to the number of users in the team, but our flexible licensing policy makes it easy to adopt and manage the tool. Here are the main particularities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The license is calculated based on the number of people in the team who leverage the repositories (that will be analyzed), rather than the number of machines involved.&lt;/li&gt;
&lt;li&gt;One license can cover developers across several departments/projects.&lt;/li&gt;
&lt;li&gt;There are no restrictions on code volume, diagnostic rules, and new versions.&lt;/li&gt;
&lt;li&gt;Technical support comes directly from the analyzer developers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Two main types of licenses&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Team&lt;/strong&gt;: suitable for small teams up to nine users. It includes basic analyzer features.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enterprise:&lt;/strong&gt; a good option for large teams. It has more features, more usage scenarios, and priority technical support.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Team license
&lt;/h3&gt;

&lt;p&gt;The Team license is designed for &lt;strong&gt;small teams&lt;/strong&gt; of up to nine developers (inclusive).&lt;/p&gt;

&lt;p&gt;It includes basic support: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;assistance with integrating into the development process;&lt;/li&gt;
&lt;li&gt;prompt resolution of analyzer issues;&lt;/li&gt;
&lt;li&gt;several analyzer developers simultaneously assisting in a single technical support request.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The license includes all core analyzer functionality but has some functional limitations related to development process quality management, such as: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;automatic notifications&lt;/li&gt;
&lt;li&gt;integration with cloud services&lt;/li&gt;
&lt;li&gt;partial restrictions on incremental analysis&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;/strong&gt; For more details on what each PVS-Studio license includes, please refer to &lt;a href="https://pvs-studio.com/en/order/license/" rel="noopener noreferrer"&gt;this page&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Enterprise license
&lt;/h3&gt;

&lt;p&gt;The Enterprise license is designed for medium and large teams and has no restrictions on the use of the analyzer's functionalities. A single Enterprise license can be used by multiple teams within a company, including several small teams.&lt;/p&gt;

&lt;p&gt;It includes all the basic analyzer functionality and additional features specific to this licensing option. These include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;adaptation of PVS-Studio functionality to the specifics of the customers' ecosystem;&lt;/li&gt;
&lt;li&gt;several analyzer developers simultaneously assisting in multiple technical support requests;&lt;/li&gt;
&lt;li&gt;analysis of files changed since the previous build;&lt;/li&gt;
&lt;li&gt;on-premise and CI-driven usage of incremental analysis.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;You can request a trial Enterprise license &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=1358" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Quick start
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Relevant analyzer warnings
&lt;/h3&gt;

&lt;p&gt;If you're new to static analysis tools and want to explore their functionality, you can use the &lt;strong&gt;Best Warnings&lt;/strong&gt; mechanism that is designed specifically for the first encounter with PVS-Studio static analyzer. &lt;/p&gt;

&lt;p&gt;It highlights the most important and reliable warnings in the project report. To display them, click the &lt;strong&gt;Best&lt;/strong&gt; button:&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%2F933kpw48h3ozwvoc7l4y.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%2F933kpw48h3ozwvoc7l4y.png" alt=" " width="751" height="316"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The report displays ten warnings, giving a quick overview of the analyzer's potential without reviewing the entire list of results.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to work with legacy code using static analysis
&lt;/h3&gt;

&lt;p&gt;PVS-Studio has a mass suppression mechanism intended for use when integrating the analyzer into an existing codebase with a large number of pre-existing warnings.&lt;/p&gt;

&lt;p&gt;Mass suppression mechanism helps focus on analyzing new code while preserving the ability to return to warnings found in legacy code later.&lt;/p&gt;

&lt;p&gt;As a result, the report will include only warnings related to newly written or modified code. This mode doesn't require any changes to the project's source files.&lt;/p&gt;

&lt;p&gt;For more details, you can refer to the &lt;a href="https://pvs-studio.com/en/docs/manual/0032/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next?
&lt;/h2&gt;

&lt;p&gt;If you still haven't tried the analyzer on your project, feel free to evaluate its performance. You can obtain a trial license &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=1358" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To learn more, you can read a &lt;a href="https://pvs-studio.com/en/docs/" rel="noopener noreferrer"&gt;full version of the documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you have further questions about configuring the analyzer or understanding its behavior, you can leave a comment below the article or contact us via the &lt;a href="https://pvs-studio.com/en/about-feedback/" rel="noopener noreferrer"&gt;feedback form&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Closed-world assumption in Java</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Thu, 26 Mar 2026 14:41:44 +0000</pubDate>
      <link>https://forem.com/pvsdev/closed-world-assumption-in-java-254a</link>
      <guid>https://forem.com/pvsdev/closed-world-assumption-in-java-254a</guid>
      <description>&lt;p&gt;Building Native Image for a Java application requires configuration of reflection, proxies, and other dynamic Java mechanisms. But why is this necessary if the JVM handles all of this automatically? To answer that, we need to look at the differences between static and dynamic compilation in Java.&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%2F9qte25gedz9ycqfkd2p0.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%2F9qte25gedz9ycqfkd2p0.png" alt="1357_cwa_in_java/image1.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Issue
&lt;/h2&gt;

&lt;p&gt;At PVS-Studio, we are currently designing &lt;a href="https://pvs-studio.com/en/blog/terms/0046/" rel="noopener noreferrer"&gt;new static analyzers&lt;/a&gt; for JavaScript/TypeScript and Go to complement our existing tools. The Java team was tasked with developing the first version of the JavaScript/TypeScript analyzer. To avoid distributing a JRE and to gain performance profit, we decided to build the JavaScript/TypeScript analyzer into &lt;a href="https://www.graalvm.org/latest/reference-manual/native-image/" rel="noopener noreferrer"&gt;Native Image&lt;/a&gt;, i.e., to turn the Java application into a native program.&lt;/p&gt;

&lt;p&gt;However, everything had its price, even performance. &lt;a href="https://www.graalvm.org/" rel="noopener noreferrer"&gt;GraalVM&lt;/a&gt; immediately laid out its requirements: we had to explicitly specify in the configuration which classes would be accessed via reflection, which proxies would be created, which resources would be included in the binary, and which functions would be called via the &lt;a href="https://docs.oracle.com/en/java/javase/25/core/foreign-function-and-memory-api.html" rel="noopener noreferrer"&gt;Foreign Function &amp;amp; Memory API&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This raised a natural question: "Why does the VM automatically handle all dynamic behavior, while native build require configuration files?"&lt;/p&gt;

&lt;p&gt;The intuitive response: "That's just how GraalVM works." But that explanation feels unsatisfying at all. It gave the impression that Native Image might be an immature technology or a questionable compromise. Of course, that's not the case. To understand why, we need to step back from Java for a moment and look at a more fundamental question: what does it actually mean to execute a program?&lt;/p&gt;

&lt;h2&gt;
  
  
  Recap: What is a program, and how is it executed?
&lt;/h2&gt;

&lt;p&gt;When we write code in Java, Kotlin, or another object-oriented language, we work with classes, methods, and packages. However, from the processor's perspective, none of this exists. All code ultimately gets converted into binary data: sets of instructions, constants, and data. &lt;/p&gt;

&lt;p&gt;To pass control to the section or access data, the processor needs the exact address. These addresses can be obtained in several ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fixed (hard-coded);&lt;/li&gt;
&lt;li&gt;relative (calculated based on the current position);&lt;/li&gt;
&lt;li&gt;dynamic (using tables, pointers, and late binding).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In statically compiled languages such as C, C++, Go, or Rust, address resolution happens during compilation via the compiler and linker.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A linker is a program that combines object files (output by the compiler) into a single executable file or library. It matches method calls with their definitions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;During the linking, all symbols and invocation points are known, so the linker has no trouble building the binary.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A symbol is a named entity in the code (a function and a variable).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Dynamic Java
&lt;/h2&gt;

&lt;p&gt;Unlike statically compiled languages, where all addresses are resolved by the time the program runs and no additional loading occurs, Java was originally designed as a dynamic runtime environment. Its model is fundamentally different: the program is not compiled into a finished binary with fixed addresses, but remains a set of bytecode that is interpreted and optimized at runtime.&lt;/p&gt;

&lt;p&gt;Several fundamental language properties help the virtual machine implement this behavior:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;classes are not loaded entirely during the startup, but as needed via &lt;code&gt;ClassLoader&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;in bytecode, method calls are represented by symbolic references rather than addresses;&lt;/li&gt;
&lt;li&gt;the actual method that will be called is determined only at runtime;&lt;/li&gt;
&lt;li&gt;class metadata (fields, methods, annotations) is preserved and accessible at runtime.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;A symbolic reference refers to a class instance using its name rather than its direct memory address. For example, it can call &lt;code&gt;PrintWriter#println&lt;/code&gt; instead of going to the &lt;code&gt;0x954A&lt;/code&gt; address.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This allows Java to have such goodies as reflection, dynamic proxies, &lt;code&gt;ServiceLoader&lt;/code&gt;, and DI frameworks like &lt;a href="https://spring.io/" rel="noopener noreferrer"&gt;Spring&lt;/a&gt;, &lt;a href="https://micronaut.io/" rel="noopener noreferrer"&gt;Micronaut&lt;/a&gt;, or &lt;a href="https://quarkus.io/" rel="noopener noreferrer"&gt;Quarkus&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;At the core of this dynamism is an architecture in which the virtual machine serves as the center of the Java "universe." The program "revolves" around the JVM: it retrieves addresses from it, calls methods, and entrusts the entire execution process to it. &lt;/p&gt;

&lt;p&gt;Essentially, the JVM serves as the central hub of execution:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;all classes revolve around it;&lt;/li&gt;
&lt;li&gt;all calls go through it;&lt;/li&gt;
&lt;li&gt;all decisions about what exactly will be called are made by it at runtime.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words, a Java application does not contain fixed addresses—the JVM determines them.&lt;/p&gt;

&lt;p&gt;Next, I'll try to explain how the JVM works on the example of a BMW axle.&lt;/p&gt;

&lt;h2&gt;
  
  
  The JVM is like the BMW X6 axle
&lt;/h2&gt;

&lt;p&gt;Imagine the JVM not as a virtual machine, but as the axle of a BMW X6 powered by a 4.4-liter S63B44T4 V8 engine producing 625 horsepower.&lt;/p&gt;

&lt;p&gt;The whole system can look impressive: the engine delivers hundreds of horsepower, the electronics are sophisticated, and it has a multi-link rear suspension. But it is the axle that connects rotation, load, and motion into a single, coherent system.&lt;/p&gt;

&lt;p&gt;The JVM plays that very role. It's the structural element through which all aspects of program execution are coordinated and brought together.&lt;/p&gt;

&lt;p&gt;To be more specific, the JVM:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;controls class loading;&lt;/li&gt;
&lt;li&gt;allows symbolic references;&lt;/li&gt;
&lt;li&gt;stores and interprets metadata;&lt;/li&gt;
&lt;li&gt;determines which method implementation to invoke;&lt;/li&gt;
&lt;li&gt;supports reflection, proxies, and dynamic behavior substitution.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's get even more specific. The Java program says, "I want to call a method named &lt;code&gt;equals&lt;/code&gt; with the &lt;code&gt;(Object)Object&lt;/code&gt; signature." The JVM responds: "Okay, let's find its address and call it."&lt;/p&gt;

&lt;p&gt;As long as this "axle" exists, everything works as it should. But Native Image removes it, leaving nothing to coordinate the components with.&lt;/p&gt;

&lt;h2&gt;
  
  
  Leap of faith: Native Java build
&lt;/h2&gt;

&lt;p&gt;A native build attempts to turn a program designed to run within a complex dynamic environment into a self-contained binary that runs directly on the operating system.&lt;/p&gt;

&lt;p&gt;This means that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the JVM, as the central hub, disappears;&lt;/li&gt;
&lt;li&gt;decisions previously made at runtime must now be made ahead of time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The linker requires a complete and closed call graph, and this is where a fundamental contradiction arises.&lt;/p&gt;

&lt;p&gt;In Java:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;classes can be loaded dynamically;&lt;/li&gt;
&lt;li&gt;methods can be called via reflection;&lt;/li&gt;
&lt;li&gt;proxies can be generated at runtime.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A static linker views it as a black box. In general, it is impossible to determine in advance exactly what will be called. What should we do?&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not just enable everything?
&lt;/h2&gt;

&lt;p&gt;At first glance, the solution seems obvious: if we can't determine what will be used, enable everything. In practice, however, this approach does not work.&lt;/p&gt;

&lt;p&gt;First, it's binary size. Including all classes, metadata, and JVM infrastructure means increasing the binary size by several times. One of the key advantages of Native Image is lost.&lt;/p&gt;

&lt;p&gt;Second, it's compilation performance. Analyzing and parsing the data requires significantly more time and memory.&lt;/p&gt;

&lt;p&gt;But even if we're ready to sacrifice size and build time, we'd still face a third problem: reflection wouldn't work automatically anyway. What matters is not just the existence of classes, but the preservation of specific metadata: constructors, methods, and signatures. Without knowing in advance what will be accessed via reflection, it's impossible to retain all required metadata correctly.&lt;/p&gt;

&lt;p&gt;So, the include-everything strategy fails both in theory and in practice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Graal Native Image Configuration
&lt;/h2&gt;

&lt;p&gt;Native Image is based on the closed-world assumption: all possible execution paths must be known at compile time. The build process relies on reachability analysis:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a call graph is constructed;&lt;/li&gt;
&lt;li&gt;everything not included in this graph is considered unreachable and removed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Java's dynamic mechanisms break this rule: reflection, proxies, and resources introduce hidden entry points—code paths that may be invoked at runtime but are invisible during analysis. Even code that seems static can generate such implicit calls, which means it requires configuration for native compilation.&lt;/p&gt;

&lt;p&gt;We encountered this issue when we needed to read a value from the Windows Registry within the analyzer. We couldn't find a suitable library, so we decided to use the relatively new &lt;a href="https://docs.oracle.com/en/java/javase/25/core/foreign-function-and-memory-api.html" rel="noopener noreferrer"&gt;Foreign Function &amp;amp; Memory API&lt;/a&gt;, which allows native methods to be called directly from Java.&lt;/p&gt;

&lt;p&gt;The actual registry access code would be interesting but too complex for an example, so let's simplify it to the standard "Hello, World" output in the console.&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;Sandbox&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;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;throws&lt;/span&gt; &lt;span class="n"&gt;Throwable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Linker&lt;/span&gt; &lt;span class="n"&gt;linker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Linker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nativeLinker&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// (1)&lt;/span&gt;
    &lt;span class="n"&gt;MethodHandle&lt;/span&gt; &lt;span class="n"&gt;printf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;linker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;downcallHandle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="c1"&gt;// (2)&lt;/span&gt;
        &lt;span class="n"&gt;linker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;defaultLookup&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;findOrThrow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"printf"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// (3)&lt;/span&gt;
        &lt;span class="n"&gt;FunctionDescriptor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ValueLayout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JAVA_INT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ValueLayout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ADDRESS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Arena&lt;/span&gt; &lt;span class="n"&gt;arena&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Arena&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ofConfined&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// (4)&lt;/span&gt;
      &lt;span class="n"&gt;MemorySegment&lt;/span&gt; &lt;span class="n"&gt;cString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arena&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;allocateFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, world!&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="c1"&gt;// (5)&lt;/span&gt;
      &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cString&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// (6)&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;Here, we obtain a linker for native calls (1); create a &lt;a href="https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/invoke/MethodHandle.html" rel="noopener noreferrer"&gt;MethodHandle&lt;/a&gt; for the &lt;a href="https://en.cppreference.com/w/cpp/io/c/fprintf" rel="noopener noreferrer"&gt;printf&lt;/a&gt; method (2); resolve the method name at runtime (3); open an &lt;a href="https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/foreign/Arena.html" rel="noopener noreferrer"&gt;Arena&lt;/a&gt;, a scope for managing off-heap memory (4); allocate a block within it, write a C-style string into it (5), and call the method via the &lt;a href="https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/invoke/MethodHandle.html" rel="noopener noreferrer"&gt;MethodHandle&lt;/a&gt; (6).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;MethodHandle is a reference to executable code. You can learn more about this technology &lt;a href="https://pvs-studio.com/en/blog/posts/java/1266/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;FYI, the equivalent code in C looks 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="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;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, world!&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="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;On the JVM, this code works correctly, but when the Native Image runs with no appropriate configuration, an error occurs. The stack trace shows that the Native Image can't set up the mechanism for calling the native method: it doesn't know how to pass arguments or receive the result because the call signature wasn't known at compile time. Graal is asking us to add information about the call point:&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="s"&gt;"foreign"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;"downcalls"&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="s"&gt;"returnType"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"jint"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// (1)&lt;/span&gt;
        &lt;span class="s"&gt;"parameterTypes"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s"&gt;"void*"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;// (2)&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;This configuration doesn't describe a specific method, but rather the form of a native call that may occur at runtime. From this, Graal learns the size of the return value, how it should be received and interpreted after control is returned (1), as well as the argument size, how it's passed to native code, and which passing rules should be followed (2).&lt;/p&gt;

&lt;p&gt;In other words, the configuration replaces decisions that the JVM would normally make at runtime.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;What can we take away from this? &lt;/p&gt;

&lt;p&gt;The JVM can handle everything on its own because it is the runtime decision-making center. Native Image can't rely on such improvisation because it makes all decisions ahead of time.&lt;/p&gt;

&lt;p&gt;Configuration in GraalVM Native Image is not a quirk, a limitation, or a design flaw. It is a direct consequence of Java's dynamic nature and the attempt to bring it into the world of static compilation.&lt;/p&gt;

&lt;p&gt;If the JVM is the axle around which a Java application revolves, the Native Image is a snapshot of that system frozen at a specific moment. And to ensure that this snapshot is correct, we need to explicitly specify in the configuration exactly what should be included.&lt;/p&gt;

</description>
      <category>java</category>
      <category>jvm</category>
      <category>graalvm</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>S&amp;Box game engine: Inspecting grains of sand</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Wed, 25 Mar 2026 14:53:17 +0000</pubDate>
      <link>https://forem.com/pvsdev/sbox-game-engine-inspecting-grains-of-sand-1fak</link>
      <guid>https://forem.com/pvsdev/sbox-game-engine-inspecting-grains-of-sand-1fak</guid>
      <description>&lt;p&gt;The market for modern game engines is steadily growing; more and more studios are choosing smaller engines rather than one of the two major players (or, given recent events, just one). Today, let's discuss one of the newcomers to the industry, S&amp;amp;Box. In this case, the newcomer isn't as simple as it seems. To learn more about the project and the errors we detected using PVS-Studio, continue reading the article. &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%2Fmynbjqdilqgcs0vlgq5a.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%2Fmynbjqdilqgcs0vlgq5a.png" alt="1356_S_Box/image1.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://sbox.game/" rel="noopener noreferrer"&gt;S&amp;amp;Box&lt;/a&gt; is a brand-new game engine from the well-known Facepunch studio, which brought us iconic projects like Rust and Garry's Mod. Both are among the best-selling games on Steam. However, Garry's Mod plays a much more significant role here than being just one of the studio's games. S&amp;amp;Box is the fully realized spiritual successor to all the ideas Garry Newman—the creator of both Garry's Mod and S&amp;amp;Box—wanted to see in Garry's Mod. &lt;/p&gt;

&lt;p&gt;S&amp;amp;Box is more than just a game engine. It's an entertainment platform for expressing creativity, where you can play, create, and even monetize your content.&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%2F2d13teratmhy8eh6vcnq.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%2F2d13teratmhy8eh6vcnq.png" alt="1356_S_Box/image2.png" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;S&amp;amp;Box projects are written in the latest C# 14, and the engine is built on .NET 10. Key features include real-time update support, action graphs (no-code), and shader graphs similar to those in Blender.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;. If you'd like to learn about the new features in C# 14, we have an &lt;a href="https://pvs-studio.com/en/blog/posts/csharp/1301/" rel="noopener noreferrer"&gt;overview article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Notably, this is the first third-party project (not from Valve) to use Source 2, and S&amp;amp;Box is now open-source as well!&lt;/p&gt;

&lt;p&gt;Of course, we couldn't overlook the brand-new C# project that leverages all the power of the latest .NET! In case you've forgotten, or if this is your first time joining us, we're the team behind PVS-Studio static analyzer, and we love checking open-source projects! This enables us to evaluate the analyzer capabilities and share the results with you.&lt;/p&gt;

&lt;p&gt;Today, we'll discuss the benefits of using static code analyzers during development, especially if you plan to share your project online &amp;gt;:)&lt;/p&gt;

&lt;p&gt;The project code is available on &lt;a href="https://github.com/Facepunch/sbox-public" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;; the analysis is performed on one of the release commits, &lt;a href="https://github.com/Facepunch/sbox-public/commit/f69cd482fc09699bae64c3c64f9f8e64ab06119a" rel="noopener noreferrer"&gt;f69cd48&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's check the project
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What errors did we pick?
&lt;/h3&gt;

&lt;p&gt;In this article, I'll break down warnings from the BEST tab.&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%2Fdnkc5xc2wm0d9m8yhvmf.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%2Fdnkc5xc2wm0d9m8yhvmf.png" alt="1356_S_Box/image3.png" width="360" height="66"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This feature is useful for providing an initial warning overview during a test run of the analyzer. It can also be used to identify high-priority warnings or as a starting point when reviewing a report. The way you use it is up to you.&lt;/p&gt;

&lt;p&gt;The feature incorporates a fairly simple yet efficient mechanism. In short, the analyzer has three warning levels (High, Medium, and Low). These are &lt;strong&gt;certainty levels&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Why might you need them? That's simple: the analyzer is a tool that aims to understand the full context of a project, but technical limitations prevent it from doing so. To avoid confusing warnings where the analyzer is nearly 100% certain an error exists with those where it merely points out suspicious code that may not contain errors, we divided them into three levels.&lt;/p&gt;

&lt;p&gt;For the standard analyzer workflow, we recommend keeping the High and Medium levels enabled and leaving the Low one for situations when you have time to review the warnings. The analyzer includes a feature that always highlights code smells that other people working with the code may also mistake for an error.&lt;/p&gt;

&lt;p&gt;If you look at the code while working with the analyzer to determine whether it's actually an error or not, others may not bother doing so :)&lt;/p&gt;

&lt;h3&gt;
  
  
  It's time to review code
&lt;/h3&gt;

&lt;p&gt;Let's start with a quick warm-up:&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="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;CollapseEdge&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;GetVerticesConnectedToHalfEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;hFullEdge&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;hVertexA&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;hVertexB&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;hEdgeA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hFullEdge&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;hEdgeB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hFullEdge&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OppositeEdge&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;hFaceA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hEdgeA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Face&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;hFaceB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hEdgeB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Face&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
  &lt;span class="c1"&gt;// Disconnect the edge that is being collapsed&lt;/span&gt;
  &lt;span class="c1"&gt;// from the faces and other edges.&lt;/span&gt;
  &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;True&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hEdgeA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsValid&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;  &lt;span class="n"&gt;hEdgeB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsValid&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;hEdgeA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsValid&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;hEdgeA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsValid&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;pNewVertex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hNewVertex&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;hNextEdgeA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hEdgeA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NextEdge&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;hPrevEdgeA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="n"&gt;FindPreviousEdgeInFaceLoop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;hEdgeA&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;hNextEdgeB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hEdgeB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NextEdge&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;hPrevEdgeB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="n"&gt;FindPreviousEdgeInFaceLoop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;hEdgeB&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;Try to find an error here.&lt;/p&gt;

&lt;p&gt;The answer is just around the corner...&lt;/p&gt;

&lt;p&gt;PVS-Studio warning: V3001 There are identical sub-expressions 'hEdgeA.IsValid' to the left and to the right of the '&amp;amp;&amp;amp;' operator. HalfEdgeMesh.cs 2094&lt;/p&gt;

&lt;p&gt;If you look closely, the error becomes obvious. &lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;If&lt;/code&gt; condition, two objects with similar names, &lt;code&gt;hEdgeA&lt;/code&gt; and &lt;code&gt;hEdgeB&lt;/code&gt;, are compared. Well, in reality, they aren't... The code shows that this was the intended behavior. However, something went wrong: &lt;code&gt;hEdgeA&lt;/code&gt; was compared to itself, and I think the result is obvious. Such fragments often contain typos. There are many variables and operations involving them, and they are quite similar! Why struggle when you can use a tool that detects such errors?&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting priorities
&lt;/h3&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;void&lt;/span&gt; &lt;span class="nf"&gt;RewriteTypeNames&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;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;attribute&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Attributes&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;attribute&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BoundAttribute&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsGenericTypedProperty&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;attribute&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TypeName&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="p"&gt;{....}&lt;/span&gt;

    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;attribute&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TypeName&lt;/span&gt; &lt;span class="o"&gt;==&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="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attribute&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BoundAttribute&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsDelegateProperty&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="p"&gt;{....}&lt;/span&gt;

    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;attribute&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TypeName&lt;/span&gt; &lt;span class="o"&gt;==&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="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attribute&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BoundAttribute&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsEventCallbackProperty&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="p"&gt;{....}&lt;/span&gt;

    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;attribute&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TypeName&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="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;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. ComponentGenericTypePass.cs 346&lt;/p&gt;

&lt;p&gt;If we look closely, it's easy to spot the issue, especially with a hint from the analyzer. Let's dig a little deeper and see what's wrong:&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;attribute&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BoundAttribute&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsGenericTypedProperty&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;attribute&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TypeName&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most likely, developers had the following order in mind (as shown in 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;attribute&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BoundAttribute&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsGenericTypedProperty&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;attribute&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TypeName&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, this is how it turned out:&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;attribute&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BoundAttribute&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsGenericTypedProperty&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="nb"&gt;false&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;attribute&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TypeName&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As the analyzer message suggests, &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; has a higher precedence than &lt;code&gt;??&lt;/code&gt;, which results in a scenario that makes no sense. &lt;/p&gt;

&lt;p&gt;It's strange that everything else is correct, and the check works properly (even the parentheses are used!), but that only confirms the error.&lt;/p&gt;

&lt;p&gt;The worst part is that the error occurred again despite all this. The developers copied and pasted the code snippet, thus spreading it further—you can see this just below the error:&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;void&lt;/span&gt; &lt;span class="nf"&gt;RewriteTypeNames&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;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;childContent&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ChildContents&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;childContent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BoundAttribute&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsGenericTypedProperty&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;childContent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TypeName&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="p"&gt;{....}&lt;/span&gt;

     &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;childContent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsParameterized&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="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;h3&gt;
  
  
  A dangerous scenario
&lt;/h3&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;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Hotload&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;AddUpgrader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;IInstanceUpgrader&lt;/span&gt; &lt;span class="n"&gt;upgrader&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="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;AddUpgrader&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TUpgrader&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;where&lt;/span&gt; &lt;span class="n"&gt;TUpgrader&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IInstanceUpgrader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;AddUpgrader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;TUpgrader&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;IInstanceUpgrader&lt;/span&gt; &lt;span class="nf"&gt;GetUpgrader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;upgraderType&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;internal&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;FormatAssemblyName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;AssemblyName&lt;/span&gt; &lt;span class="n"&gt;name&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;AssemblyNameFormatter&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;
             &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Invoke&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="o"&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;ToString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;FormatAssemblyName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;Assembly&lt;/span&gt; &lt;span class="k"&gt;asm&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;FormatAssemblyName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;asm&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetName&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;What do you think is wrong with this code fragment? NRE can occur in one of the scenarios. Unfortunately, this error is quite common. &lt;/p&gt;

&lt;p&gt;Let's shorten the code and take a closer look:&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;string&lt;/span&gt; &lt;span class="nf"&gt;FormatAssemblyName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;AssemblyName&lt;/span&gt; &lt;span class="n"&gt;name&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;AssemblyNameFormatter&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;
           &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Invoke&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="o"&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;ToString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;FormatAssemblyName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;Assembly&lt;/span&gt; &lt;span class="k"&gt;asm&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;FormatAssemblyName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;asm&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetName&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;PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v3105/" rel="noopener noreferrer"&gt;V3105&lt;/a&gt; The result of null-conditional operator is dereferenced inside the 'FormatAssemblyName' method. NullReferenceException is possible. Inspect the first argument 'asm?.GetName()'. Hotload.cs 324&lt;/p&gt;

&lt;p&gt;The developers expected the &lt;code&gt;asm&lt;/code&gt; parameter to be &lt;code&gt;null&lt;/code&gt; in the &lt;code&gt;FormatAssemblyName(Assembly asm)&lt;/code&gt; method: &lt;code&gt;FormatAssemblyName(asm?.GetName())&lt;/code&gt;. However, they didn't expect that in &lt;code&gt;FormatAssemblyName( AssemblyName name )&lt;/code&gt;.  There are two scenarios: the first is &lt;code&gt;name = null&lt;/code&gt;, and the second is &lt;code&gt;AssemblyNameFormatter = null&lt;/code&gt; and &lt;code&gt;name = null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the first case, everything works fine, since &lt;code&gt;AssemblyNameFormatter&lt;/code&gt; handles the scenario. Meanwhile, the second one is erroneous because &lt;code&gt;name&lt;/code&gt; is used without being checked, and an NRE occurs when the &lt;code&gt;name.ToString()&lt;/code&gt; method is called.&lt;/p&gt;

&lt;h3&gt;
  
  
  They forgot something
&lt;/h3&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="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;UnregisterTypes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;Assembly&lt;/span&gt; &lt;span class="n"&gt;assembly&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;assetSourceType&lt;/span&gt; &lt;span class="o"&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;BaseGameMount&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;types&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;assembly&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetTypes&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;Where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; 
                  &lt;span class="n"&gt;assetSourceType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsAssignableFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;t&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="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsAbstract&lt;/span&gt; &lt;span class="p"&gt;);&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="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ident&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;Sources&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToArray&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;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetType&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;Assembly&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;assembly&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;continue&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;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsMounted&lt;/span&gt; &lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="n"&gt;PendingMounts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;ident&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ShutdownInternal&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;Sources&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;ident&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;This code tells a sad story of a forgotten variable and an unexecuted method due to deferred execution.&lt;/p&gt;

&lt;p&gt;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 'Where' LINQ method with deferred execution is never used. The method will not be executed. MountHost.cs 114&lt;/p&gt;

&lt;p&gt;If we look at the &lt;code&gt;types&lt;/code&gt; variable and the value the developers assigned to it, we'll see a selection of certain objects:&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;types&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;assembly&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetTypes&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;Where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; 
                  &lt;span class="n"&gt;assetSourceType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsAssignableFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;t&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="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsAbstract&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, no filtering will happen because &lt;code&gt;types&lt;/code&gt; isn't mentioned anywhere else in the code. This happens because calling &lt;code&gt;Where&lt;/code&gt; doesn't execute the filtering immediately—it uses deferred execution. So, the delegate code won't be executed until the collection is iterated over.&lt;/p&gt;

&lt;p&gt;In this case, the consequences aren't that serious because no further action is expected from the delegate in &lt;code&gt;Where&lt;/code&gt;. However, if the code were different, important features could be lost, for 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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;it&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="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;filteredNames&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Where&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;=&amp;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;it&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                      &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="s"&gt;"{it}) {name}"&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;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StartsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;startLetter&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;A delegate that both applies a filter condition and prints elements along with their positions from the original collection to the console is passed to the &lt;code&gt;Where&lt;/code&gt; method. However, as you've probably already noticed, &lt;code&gt;filteredNames&lt;/code&gt; may not be specified, so the filtered collection won't be printed to the console, and filtering won't occur at all.&lt;/p&gt;

&lt;h3&gt;
  
  
  An over-check
&lt;/h3&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;static&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;IsIes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;byte&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="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;data&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;null&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="n"&gt;Length&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&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;header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Encoding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ASCII&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetString&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="mi"&gt;20&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;Length&lt;/span&gt; &lt;span class="p"&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;return&lt;/span&gt; 
   &lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StartsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s"&gt;"IESNA"&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; 
   &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StartsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s"&gt;"IESNA:LM-63"&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;PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v3053/" rel="noopener noreferrer"&gt;V3053&lt;/a&gt; An excessive expression. Examine the substrings 'IESNA' and 'IESNA:LM-63'. Bitmap.Loading.Ies.cs 242&lt;/p&gt;

&lt;p&gt;If the &lt;code&gt;IESNA&lt;/code&gt; substring is found, no further checks will be performed. If the &lt;code&gt;IESNA&lt;/code&gt; substring isn't found, then there's no point in searching for the longer &lt;code&gt;IESNA:LM-63&lt;/code&gt; substring. We usually recommend removing redundant code, but this case may be a little different.&lt;/p&gt;

&lt;p&gt;The code includes an additional check for &lt;code&gt;IESNA:LM-63&lt;/code&gt;. If the developers wanted to ensure that the IESNA standard version was exactly "LM-63," they should've written it this way:&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;header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StartsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"IESNA:LM-63"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
       &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StartsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"IES:LM-63"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are the new and old IESNA formats (modern versions use the &lt;code&gt;IES:&lt;/code&gt; prefix), but the current check doesn't meet this condition and will allow any encoding or version of the standard.&lt;/p&gt;

&lt;h3&gt;
  
  
  Forgotten Deserialize
&lt;/h3&gt;

&lt;p&gt;Can you spot an error in the following snippet?&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;JsonSerializer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Deserialize&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Vector3&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;ref&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Did you find it?&lt;/p&gt;

&lt;p&gt;Let me give you a hint.&lt;/p&gt;

&lt;p&gt;PVS-Studio warning: V3010 The return value of function 'Deserialize' is required to be utilized. PolygonMesh.Serialize.cs 54&lt;/p&gt;

&lt;p&gt;I never doubted you!&lt;/p&gt;

&lt;p&gt;All right, jokes aside—let's get to the bottom of this. We have the &lt;code&gt;ref&lt;/code&gt; modifier, and the logic works fine anyway—maybe this isn't really an issue?&lt;/p&gt;

&lt;p&gt;Deserialization occurs frequently in this code snippet. Let's take a look:&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="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;propertyName&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"TextureOrigin"&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;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TokenType&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;JsonTokenType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StartArray&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;mesh&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TextureOriginUnused&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CopyFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;JsonSerializer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Deserialize&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Vector3&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="n"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;reader&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;else&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;JsonSerializer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Deserialize&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Vector3&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;ref&lt;/span&gt; &lt;span class="n"&gt;reader&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;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;propertyName&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;TextureCoord&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;mesh&lt;/span&gt;
 &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TextureCoord&lt;/span&gt;
 &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CopyFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;JsonSerializer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Deserialize&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Vector2&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="n"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;hasTextureCoords&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;true&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="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;propertyName&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"TextureRotation"&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;mesh&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TextureRotationUnused&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CopyFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;JsonSerializer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Deserialize&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Rotation&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="n"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;reader&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="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;propertyName&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;TextureUAxis&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;mesh&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TextureUAxis&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CopyFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;JsonSerializer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Deserialize&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Vector3&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="n"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;reader&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;There are many more examples like this in the code. The point is that the return value is used for copying and other operations, but it was omitted just once. This is a very suspicious fragment, where they most likely just forgot ;_;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Release TODO
&lt;/h3&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;static&lt;/span&gt; &lt;span class="n"&gt;ConCmdAttribute&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AutoCompleteResult&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="n"&gt;GetAutoComplete&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;parts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;partial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SplitQuotesStrings&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;ConCmdAttribute&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AutoCompleteResult&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// if we have more than one part, complete a specific command&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;parts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt; &lt;span class="o"&gt;&amp;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="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="n"&gt;Members&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;parts&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;out&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;command&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;Array&lt;/span&gt;
             &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ConCmdAttribute&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AutoCompleteResult&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;//results.Add( new ConCmd.AutoCompleteResult &lt;/span&gt;
  &lt;span class="c1"&gt;//  { Command = command.Name, Description = command.Help } );&lt;/span&gt;

  &lt;span class="c1"&gt;// TODO - dig into it for auto complete&lt;/span&gt;
  &lt;span class="k"&gt;return&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;Take&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="n"&gt;ToArray&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;PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v3191/" rel="noopener noreferrer"&gt;V3191&lt;/a&gt; Iteration through the 'results' collection makes no sense because it is always empty. ConVarSystem.AutoComplete.cs 23&lt;/p&gt;

&lt;p&gt;The analyzer points out that iterating over &lt;code&gt;results&lt;/code&gt; is pointless, since the collection is always empty. And it's hard to argue with that! After all, the feature that adds anything to this collection is commented out.&lt;/p&gt;

&lt;p&gt;Based on other comments, we can draw two conclusions: the code does contain some logic and a clear intent, but part of the functionality remains marked as TODO.&lt;/p&gt;

&lt;p&gt;At first glance, that might not seem like an error—everything looks deliberate. I have a question, though: should we consider this case a poor example? Keep in mind that this project serves as a foundation for many others. The behavior and logic of numerous games will depend on how well the engine's source code is written. This fragment has been there since the release, and at the time of writing, more than six months have passed.&lt;/p&gt;

&lt;p&gt;What do you think: does this count as an issue, or is it acceptable? Share your thoughts in the comments. &lt;/p&gt;

&lt;h3&gt;
  
  
  A deadzone
&lt;/h3&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="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;OnGameControllerAxis&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;deviceId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;GameControllerAxis&lt;/span&gt; &lt;span class="n"&gt;axis&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;value&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetAxis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;);&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;float&lt;/span&gt; &lt;span class="n"&gt;triggerDeadzone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.75&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// I hate this but okay&lt;/span&gt;
  &lt;span class="n"&gt;GamepadCode&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;axis&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;GameControllerAxis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TriggerLeft&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="n"&gt;GamepadCode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LeftTrigger&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

      &lt;span class="n"&gt;GameControllerAxis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TriggerRight&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="n"&gt;GamepadCode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RightTrigger&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

      &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="n"&gt;GamepadCode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="n"&gt;OnGamepadCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;deviceId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;triggerDeadzone&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;PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v3040/" rel="noopener noreferrer"&gt;V3040&lt;/a&gt; The 'triggerDeadzone' constant of the 'float' type is compared to a value of the 'int' type. InputRouter.Input.cs 207&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;value&lt;/code&gt; variable here has the &lt;code&gt;int&lt;/code&gt; type, so comparing it to &lt;code&gt;0.75f&lt;/code&gt; seems suspicious, especially when the &lt;code&gt;&amp;gt;=&lt;/code&gt; operator is used, since the nearest values are 0 and 1. It's even more unusual to encounter such an issue in code related to controller input, where precision matters. In this case, we're dealing with the button's deadzone, so it's crucial to know exactly where it starts.&lt;/p&gt;

&lt;p&gt;It's hard to say what the developers had in mind given that the &lt;code&gt;value&lt;/code&gt; variable is an &lt;code&gt;int&lt;/code&gt; and is used in other constructs. So, it's up to the project authors to decide whether this is an error or not.&lt;/p&gt;

&lt;h3&gt;
  
  
  Schrödinger's second
&lt;/h3&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;static&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;FormatSecondsLong&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;secs&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;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;secs&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;60.0&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;var&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;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;60.0&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;var&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;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;float&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="mf"&gt;24.0&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;var&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;float&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="mf"&gt;7.0&lt;/span&gt;&lt;span class="n"&gt;f&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;secs&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;60&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;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{0} seconds"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;secs&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;m&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;60&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;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{1} minutes,&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;                                     {0} seconds"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                     &lt;span class="n"&gt;secs&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                     &lt;span class="n"&gt;m&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;h&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;48&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;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="s"&gt;"{2} hours and {1} minutes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="n"&gt;secs&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="n"&gt;h&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;d&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;7&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;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="s"&gt;"{3} days, {2} hours and {1} minutes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;secs&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;60&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="mi"&gt;24&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="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"{4} weeks, {3} days, {2} hours and {1} minutes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;secs&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;60&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="mi"&gt;24&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="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;w&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;PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v3025/" rel="noopener noreferrer"&gt;V3025&lt;/a&gt; Incorrect format. A different number of format items is expected while calling 'Format' function. Arguments not used: secs % 60. NumberExtensions.cs 102&lt;/p&gt;

&lt;p&gt;The analyzer reports that the number of parameters doesn't match the format string to which they are being passed. Let's see for ourselves.&lt;/p&gt;

&lt;p&gt;Seconds are passed in the first line, and this works fine, everything is correct:&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="n"&gt;secs&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;60&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;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{0} seconds"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;secs&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, starting from the third check, the seconds are passed but not used:&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="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;48&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;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"{2} hours and {1} minutes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="n"&gt;secs&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we look at the code as a whole, we can see that seconds are passed &lt;strong&gt;everywhere&lt;/strong&gt;. The developers may have done this to improve readability, since seconds are used to calculate minutes, hours, and so on.&lt;/p&gt;

&lt;p&gt;One might say the analyzer is wrong, but it's actually right :)&lt;/p&gt;

&lt;p&gt;It didn't lie: the format string does take more arguments than expected. If this was intentional there, what are the chances that the same will be true in other cases? To avoid any risks, consider double-checking your code to catch any unexpected issues.&lt;/p&gt;

&lt;p&gt;If you're completely confident in your code, you can use a comment to inform the compiler that it's not an issue:&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="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;48&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;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; 
  &lt;span class="s"&gt;"{2} hours and {1} minutes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secs&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//-V3025&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Despite the errors we found, the project code looks polished. Its team is working hard to fix issues and potential bugs as quickly as possible (judging by their GitHub).&lt;/p&gt;

&lt;p&gt;If you're curious to see more of what PVS-Studio detected in S&amp;amp;Box (the report lists over 1,000 errors), or if you'd like to check your own project, you can download and try the analyzer by &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=1356" rel="noopener noreferrer"&gt;clicking the link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note.&lt;/strong&gt; You've made it this far, and we want to reward you: here's your chance to sign up for an early access program for our new analyzers! The EAP is available for JavaScript, TypeScript, and Go analyzers.&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>csharp</category>
      <category>programming</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
