PVS-Studio team creates new diagnostic rules, and gradually refines the existing ones. We've recently enhanced one of the oldest diagnostic rules in the C# analyzerPVS-Studio team creates new diagnostic rules, and gradually refines the existing ones. We've recently enhanced one of the oldest diagnostic rules in the C# analyzer

How to Prevent Your Code From Turning Into Sausage That Goes Beyond the Screen

Today, we’ll talk about a bug that shows in practice and how "code sausage" can cause a series of problems related to the last line effect and careless copy-paste, as well as lead to new errors.

\ The PVS-Studio team not only creates new diagnostic rules, but also gradually refines the existing ones. For example, we've recently enhanced one of the oldest diagnostic rules in the C# analyzer, V3001, to make it detect redundant parentheses more accurately. As a result, the analyzer started detecting new bugs, one of which we show you.

\ This case was detected in the Space Engineers project; this is one of the projects in our internal regression testing database. We use a specific old project version to compare how the analyzer behaves on the same code across updates. But if we look at the latest source code, we'll find that the bug is still there. Let's take a look at the Contains function in BoundingBox.cs.

\ See the problem? Probably not.

\ Why's that? Because long and indecipherable code lines are developers' foes that should be avoided. It's very easy to make a mistake there, as you can see. Let's rewrite the code a little bit to make it clearer.

public ContainmentType Contains(BoundingSphere sphere) { Vector3 result1; Vector3.Clamp(ref sphere.Center, ref this.Min, ref this.Max, out result1); float result2; Vector3.DistanceSquared(ref sphere.Center, ref result1, out result2); float num = sphere.Radius; if ((double)result2 > (double)num * (double)num) return ContainmentType.Disjoint; return (double)this.Min.X + (double)num > (double)sphere.Center.X || (double)sphere.Center.X > (double)this.Max.X - (double)num || ((double)this.Max.X - (double)this.Min.X <= (double)num || (double)this.Min.Y + (double)num > (double)sphere.Center.Y) || ((double)sphere.Center.Y > (double)this.Max.Y - (double)num || (double)this.Max.Y - (double)this.Min.Y <= (double)num || ((double)this.Min.Z + (double)num > (double)sphere.Center.Z || (double)sphere.Center.Z > (double)this.Max.Z - (double)num)) || (double)this.Max.X - (double)this.Min.X <= (double)num ? ContainmentType.Intersects : ContainmentType.Contains; }

\ Better now, yeah? However, we have to make an effort to spot the error, though. Take a look at the last line of the logical condition:

(double)this.Max.X - (double)this.Min.X <= (double)num

\ As we can see, it duplicates the third line. The condition is enclosed in extra parentheses, but they're superfluous, as all checks are joined with the OR operator anyway.

\ In practice, there should be a check of the Z coordinate:

(double)this.Max.Z - (double)this.Min.Z <= (double)num

\ The analyzer detects it and issues a warning: V3001 There are identical sub-expressions '(double)this.Max.X - (double)this.Min.X <= (double)num' to the left and to the right of the '||' operator.

\ This is a good example of how a static analyzer complements code review because it's strenuous to manually discern a little typo in such a massive line. We like to call such code "code sausage"—and we've already written a note about how it lures bugs to your code.

\ The "last line effect" is also shown in all its glory. Typos most often appear at the end of similar code fragments. Technically, we can't talk about lines, since there is a single line. However, the idea still applies: the error occurred in the very last segment of a long, repetitive block.

\ The bug came from a copy-paste typo. Most likely, developers have copied one sub-expression, pasted it as a new one, and just forgotten to modify it. However, that's not all: this entire line with the error has been copied again and shows up just a few lines below, in the nearby Contains function:

public void Contains(ref BoundingSphere sphere, out ContainmentType result) { .... if ((double)result2 > (double)num * (double)num) result = ContainmentType.Disjoint; else result = (double)this.Min.X + (double)num > (double)sphere.Center.X || (double)sphere.Center.X > (double)this.Max.X - (double)num || ((double)this.Max.X - (double)this.Min.X <= (double)num || (double)this.Min.Y + (double)num > (double)sphere.Center.Y) || ((double)sphere.Center.Y > (double)this.Max.Y - (double)num || (double)this.Max.Y - (double)this.Min.Y <= (double)num || ((double)this.Min.Z + (double)num > (double)sphere.Center.Z || (double)sphere.Center.Z > (double)this.Max.Z - (double)num)) || (double)this.Max.X - (double)this.Min.X <= (double)num ? ContainmentType.Intersects : ContainmentType.Contains; }

It's the same issue with the same warning from the analyzer.

Conclusion

There's no need to go into a long explanation of why this code is problematic, as well as how it should be changed to avoid specific errors. Our readers probably already know that it all comes down to following these tips:

  1. Use table-style code formatting.
  2. Place the similar code in functions.
  3. Avoid redundant operations. For example, instead of type casting of (double)num everywhere, we could simply declare the num variable as double.
  4. Run PVS-Studio static analyzer regularly for additional control.

\

Market Opportunity
PVS Logo
PVS Price(PVS)
$0.002553
$0.002553$0.002553
-2.52%
USD
PVS (PVS) Live Price Chart
Disclaimer: The articles reposted on this site are sourced from public platforms and are provided for informational purposes only. They do not necessarily reflect the views of MEXC. All rights remain with the original authors. If you believe any content infringes on third-party rights, please contact service@support.mexc.com for removal. MEXC makes no guarantees regarding the accuracy, completeness, or timeliness of the content and is not responsible for any actions taken based on the information provided. The content does not constitute financial, legal, or other professional advice, nor should it be considered a recommendation or endorsement by MEXC.

You May Also Like

Over $145M Evaporates In Brutal Long Squeeze

Over $145M Evaporates In Brutal Long Squeeze

The post Over $145M Evaporates In Brutal Long Squeeze appeared on BitcoinEthereumNews.com. Crypto Futures Liquidations: Over $145M Evaporates In Brutal Long Squeeze
Share
BitcoinEthereumNews2026/01/16 11:35
Today’s Wordle #1552 Hints And Answer For Thursday, September 18th

Today’s Wordle #1552 Hints And Answer For Thursday, September 18th

The post Today’s Wordle #1552 Hints And Answer For Thursday, September 18th appeared on BitcoinEthereumNews.com. How to solve today’s Wordle. SOPA Images/LightRocket via Getty Images I posted the Wordle Wednesday riddle yesterday, but somehow had deleted it when the post went live, so the riddle itself went up late. If you missed it, my apologies. In any case, the solution is below, but first, here was the (late) riddle: “I’m the beginning of the end and the end of time and space. I am in everything and surround every place. What am I?” The answer: The letter “E”. It’s the beginning of End and the end of timE and spacE. It’s in evErything and surrounds Every placE. Kind of clever. It would be much harder if you heard the riddle spoken. Looking for Tuesday’s Wordle? Check out our guide right here. How To Play Wordle Wordle is a daily word puzzle game where your goal is to guess a hidden five-letter word in six tries or fewer. After each guess, the game gives feedback to help you get closer to the answer: Green: The letter is in the word and in the correct spot. Yellow: The letter is in the word, but in the wrong spot. Gray: The letter is not in the word at all. Use these clues to narrow down your guesses. Every day brings a new word, and everyone around the world is trying to solve the same puzzle. Some Wordlers also play Competitive Wordle against friends, family, the Wordle Bot or even against me, your humble narrator. See rules for Competitive Wordle toward the end of this post. Today’s Wordle Hints And Answer Wordle Bot’s Starting Word: SLATE My Starting Word Today: TRAIL (189 words remaining) The Hint: This Wordle cuts to the bone. The Clue: This Wordle starts with a silent letter. Okay, spoilers below! The answer is coming! .…
Share
BitcoinEthereumNews2025/09/18 09:05
Banco Santander Launches Retail Crypto Trading via Openbank in Germany

Banco Santander Launches Retail Crypto Trading via Openbank in Germany

TLDR Banco Santander has launched retail crypto trading through its online bank, Openbank. German customers can now trade Bitcoin, Ether, Litecoin, Polygon, and Cardano on Openbank. The service will expand to Spanish clients in the coming weeks and include more tokens. Openbank charges a 1.49% fee per transaction, with no custody fees involved. Banco Santander [...] The post Banco Santander Launches Retail Crypto Trading via Openbank in Germany appeared first on CoinCentral.
Share
Coincentral2025/09/18 02:56