Checker ShortCircuit

belongs to group Basic
Identify where a logical bitwise operation is used instead of a logical Boolean operation

Frameworks supported by this checker

  • java up to 11
  • android up to API level 28
  • dotnet

Warnings generated by this checker

  • ANDAgainstConstantWarning: an & operation operates on a Boolean constant [ CWE480 ]
  • InefficientSameValueANDWarning: && should be used instead of & for better efficiency [ CWE480 ]
  • InefficientSameValueORWarning: || should be used instead of | for better efficiency [ CWE480 ]
  • NonShortCircuitANDWarning: there is a suspicious use of & instead of && [ CWE768 ]
  • NonShortCircuitORWarning: there is a suspicious use of | instead of || [ CWE768 ]
  • ORAgainstConstantWarning: an | operation operates on a Boolean constant [ CWE480 ]

Options accepted by this checker

  • none

Annotations understood by this checker

  • none


Description

Java has a bitwise and a logical-AND operation on Booleans, that is, & and &&. Similarly, Java has a bitwise and a logical-OR operation | and ||. The difference is that the logical operations have a short circuit semantics, that is, if the evaluation of the left-hand side is enough to determine the outcome of the operation, then the right-hand side is not evaluated; the bitwise operations, instead, evaluate both sides, always, which might be incorrect is most cases, or at least inefficient.

Action: Use the logical (short-circuit) version of the operators on Booleans.

.NET has a bitwise and a logical-AND operation on Booleans, that is, & and &&. Similarly, .NET has a bitwise and a logical-OR operation | and ||. The difference is that the logical operations have a short circuit semantics, that is, if the evaluation of the left-hand side is enough to determine the outcome of the operation, then the right-hand side is not evaluated; the bitwise operations, instead, evaluate both sides, always, which might be incorrect is most cases, or at least inefficient.

Action: Use the logical (short-circuit) version of the operators on Booleans.

Examples

Consider the following code:

public class Main {
  public static void main(String[] args) {
    if (args.length == 0 | isOption(args[0]))
      System.out.println("option expected");
    else {
      ....
    }
  }

  private static boolean isOption(String s) {
    ....
  }
}

This checker issues the following warning:

Main.java:3: [ShortCircuit: NonShortCircuitORWarning] Suspicious use of | instead of ||

since the expression isOption(args[0]) is always evaluated, also when args is the empty array. This would result in an ArrayIndexOutOfBoundsException.

In this example, the programmer should replace | with ||.

Consider the following code:

using System;

namespace DocumentationExamples
{

    
    public class ShortCircuit
    {
        public static void Main(string[] args)
        {
            if (args.Length == 0 | IsOption(args[0]))
                Console.WriteLine("option expected");
            else
            {
                Console.WriteLine("ok");
            }
        }
        private static bool IsOption(string s)
        {
            return s.StartsWith("option");
        }
    }
}

This checker issues the following warning:

DocumentationExamples.cs:11: [ShortCircuit: NonShortCircuitORWarning] Suspicious use of | instead of ||

since the expression IsOption(args[0]) is always evaluated, also when args is the empty array. This would result in an IndexOutOfRangeException.

In this example, the programmer should replace | with ||.