All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sonar.plugins.csharp.S2190.html Maven / Gradle / Ivy

There is a newer version: 10.2.0.105762
Show newest version

Why is this an issue?

Having an infinite loop or recursion will lead to a program failure or a program never finishing the execution.

public int Sum()
{
    var i = 0;
    var result = 0;
    while (true) // Noncompliant: the program will never stop
    {
        result += i;
        i++;
    }
    return result;
}

This can happen in multiple scenarios.

Loop statements

while and for loops with no break or return statements that have exit conditions which are always false will be indefinitely executed.

"goto" statements

goto statement with nothing that stops it from being executed over and over again will prevent the program from the completion.

Recursion

When a recursive method call chain lacks an exit condition, the call stack will reach its limit and the program will crash due to a StackOverflowException.

int Pow(int num, int exponent)
{
  return num * Pow(num, exponent - 1); // Noncompliant: no condition under which Pow isn't re-called
}

In this example, Pow will keep calling Pow with exponent - 1 forever, until the program crashes with a StackOverflowException.

Recursion provides some benefits.

  • Simplified code: recursion can often lead to more concise and elegant code by breaking down complex problems into smaller, more manageable parts.
  • Improved code readability: compared to iterative solutions, recursive solutions can be easier to understand and reason about.

However, it has disadvantages as well.

  • Stack overflow: Recursive functions can lead to stack overflow if the recursion is too deep, potentially causing the program to crash.
  • Performance overhead: Recursive function calls can lead to poor performance due to the need to push and pop stack frames, making them potentially slower than iterative solutions.
  • Difficulty in debugging: Debugging recursive code can be challenging, as multiple recursive calls can make it harder to track the flow of execution and identify logical errors.
  • Space complexity: Recursive algorithms may require more memory compared to iterative approaches, as each recursive call adds a new frame to the call stack.
  • Lack of control: Recursion can sometimes lead to infinite loops or unexpected behavior if not properly implemented or terminated, making it crucial to have proper base cases and exit conditions.

How to fix it

The program’s logic should incorporate a mechanism to break out of the control flow loop. Here are some examples.

Code examples

  • Use a loop condition which eventually evaluates to false

Noncompliant code example

public int Sum()
{
    var i = 0;
    var result = 0;
    while (true) // Noncompliant: the program will never stop
    {
        result += i;
        i++;
    }
    return result;
}

Compliant solution

public int Sum()
{
    var i = 0;
    var result = 0;
    while (result < 1000)
    {
        result += i;
        i++;
    }
    return result;
}
  • As {rule:csharpsquid:S907} generally suggests, avoid using goto statements. Instead, you can use a loop statement or explicit recursion.

Noncompliant code example

public int Sum()
{
    var result = 0;
    var i = 0;
iteration:
    // Noncompliant: program never ends
    result += i;
    i++;
    goto iteration;
    return result;
}

Compliant solution

public int Sum()
{
    var i = 0;
    var result = 0;
    while (result < 1000)
    {
        result += i;
        i++;
    }
    return result;
}
  • For a recursion make sure there is a base case when the recursive method is not re-called.

Noncompliant code example

int Pow(int num, int exponent)
{
  return num * Pow(num, exponent - 1); // Noncompliant: no condition under which Pow isn't re-called
}

Compliant solution

int Pow(int num, int exponent)
{
  if (exponent > 1) // recursion is now conditional and stoppable
  {
    num = num * Pow(num, exponent - 1);
  }
  return num;
}

Resources

Documentation

Articles & blog posts





© 2015 - 2024 Weber Informatics LLC | Privacy Policy