DEV Community

Anastasiia Ogneva
Anastasiia Ogneva

Posted on

Common patterns of typos in programming

The developers have an endless amount of ways to make mistakes while writing code. However, sometimes we can find obvious and interesting patterns in how and where developers make mistakes. Let's talk about the code as a "magnet" for typos.

Author: Andrey Karpov

Image description

Research background
In order to test and promote the PVS-Studio static code analyzer, we check various open-source projects. If we find errors, we report about them to the authors of projects. We collect errors and write articles about the most interesting cases.

When looking at all these errors, I notice various repeating patterns of typos. With only a few exceptions, they are independent of the programming language. At least, they are common to code written in C, C++, C#, and Java. In this article, I'll outline 7 patterns that I've noticed by now:

  • The last line effect
  • The most dangerous memset function
  • The incorrect comparison functions
  • The incorrect copy functions
  • The errors related to data and time
  • The unlucky numbers: 0, 1, 2
  • The off-by-one error

The fact that these error patterns are noticeable shows that they are common. It's useful to know how to avoid potentially dangerous coding or how to find errors more efficiently during code reviews. In other words, you'll learn which code attracts errors and how to review code more carefully. PVS-Studio can indeed detect a lot of errors, but it cannot detect them all. So, more attention to them isn't out of place.

The last line effect

Image description
Here's the description of the pattern: when writing code blocks of the same type, you may make a mistake in the last block.

Let me explain it by an example of code from the Godot Engine project (C++).

String SoftBody::get_configuration_warning() const {
  ....
  Transform t = get_transform();
  if ((ABS(t.basis.get_axis(0).length() - 1.0) > 0.05 ||
       ABS(t.basis.get_axis(1).length() - 1.0) > 0.05 ||
       ABS(t.basis.get_axis(0).length() - 1.0) > 0.05)) {
    if (!warning.empty())
  ....
}
Enter fullscreen mode Exit fullscreen mode

It's a classic copy-paste error. The developers don't want to retype similar lines of code. That's why, they just double the code line:

ABS(t.basis.get_axis(0).length() - 1.0) > 0.05
Enter fullscreen mode Exit fullscreen mode

After that, they replace 0 by 1 in the second line, but they forget to replace 0 by 2 in the last line. When we separately review such code fragment, it seems surprising to find such simple error. But that's exactly how this pattern looks like.

Here's another example found in the unit tests of the LLVM (C++) project.

TEST(RegisterContextMinidump, ConvertMinidumpContext_x86_64) {
  MinidumpContext_x86_64 Context;
  ....
  Context.rax = 0x0001020304050607;
  Context.rbx = 0x08090a0b0c0d0e0f;
  ....
  Context.eflags = 0x88898a8b;
  Context.cs = 0x8c8d;
  Context.fs = 0x8e8f;
  Context.gs = 0x9091;
  Context.ss = 0x9293;    // <=
  Context.ds = 0x9495;
  Context.ss = 0x9697;    // <=
  llvm::ArrayRef<uint8_t> ContextRef(reinterpret_cast<uint8_t *>(&Context),
                                     sizeof(Context));
  ....
}
Enter fullscreen mode Exit fullscreen mode

Let's take a look at the code lines highlighted with the code comments. This code was hardly written using copy-paste, but an error is still in the last line. The developer hurried and inattentively made a typo when repeatedly writing the value into the ss register instead of the es register.

Note. Another interesting thing is that the error shows how a static analyzer complements unit testing. Unit tests can also contain errors that cause certain untested or not fully tested scenarios. However, writing unit tests for unit tests is not practical. Code analyzers will help you here.

To avoid the impression that such errors are common only in C and C++ languages, I will show you an example of the Java code. I found the following typo in the IntelliJ IDEA Community Edition project (Java).

private static boolean isBeforeOrAfterKeyword(String str, boolean trimKeyword) {
  return (trimKeyword ? LoadingOrder.BEFORE_STR.trim() :
           LoadingOrder.BEFORE_STR).equalsIgnoreCase(str) ||
         (trimKeyword ? LoadingOrder.AFTER_STR.trim() :
           LoadingOrder.AFTER_STR).equalsIgnoreCase(str) ||
         LoadingOrder.BEFORE_STR_OLD.equalsIgnoreCase(str) ||         // <=
         LoadingOrder.BEFORE_STR_OLD.equalsIgnoreCase(str);           // <=
}
Enter fullscreen mode Exit fullscreen mode

Here we notice an obvious pattern. You can see other similar examples in the old article "The last line effect".

Why did I name this pattern in such a way? The "last meters effect" from the world of mountaineering — this is my source of inspiration. I've read the observation that climbers often make a mistake at the end of a climb. The reason is not because they are tired — they are less concentrated. They mistakenly think that they've already reached the mountain top and soon they can rest, and enjoy the end of the journey. The climber loses concentration, rushes to finish the climb and does something wrong.

When writing code, developers can experience the same thing. It's boring to write code blocks of the same type. We will prove it below when we talk about the comparison functions. So, developers rush to finish a monotonous job. When writing the last code line, they are glad that they are done with routine and may start to think about what to write next.

In any case, the concentration declines, and developers make errors. Well, they can make errors randomly, but the observation says it's more likely to happen in the last code block of the same type.

The same story happens with a code review. It's boring to review the code of the same type. That's why the concentration quickly declines, and developers carelessly check the last code lines or don't check them at all. This is how errors occur in code and can remain unnoticed. When you find these errors, their simplicity can surprise.

Tip: When reviewing code, you should pay more attention to the last code lines.

To continue reading click here

Top comments (1)

Collapse
 
sloan profile image
Sloan the DEV Moderator

Hi there, we encourage authors to share their entire posts here on DEV, rather than mostly pointing to an external link. Doing so helps ensure that readers don’t have to jump around to too many different pages, and it helps focus the conversation right here in the comments section.

If you choose to do so, you also have the option to add a canonical URL directly to your post.