V6067. Two or more case-branches perform the same actions.


Анализатор обнаружил ситуацию, когда в операторе switch разные метки case содержат одинаковые фрагменты кода. Часто это свидетельствует об избыточном коде, который можно улучшить объединением меток. Но нередко одинаковые фрагменты кода могут быть причиной copy-paste программирования и являться настоящими ошибками.

Рассмотрим пример с избыточным кодом:

public static String getSymmetricCipherName(int algorithm)
{
  switch (algorithm)
  {
    ....
    case SymmetricKeyAlgorithmTags.DES:
        return "DES";
    case SymmetricKeyAlgorithmTags.AES_128:
        return "AES";
    case SymmetricKeyAlgorithmTags.AES_192:
        return "AES";
    case SymmetricKeyAlgorithmTags.AES_256:
        return "AES";
    case SymmetricKeyAlgorithmTags.CAMELLIA_128:
        return "Camellia";
    case SymmetricKeyAlgorithmTags.CAMELLIA_192:
        return "Camellia";
    case SymmetricKeyAlgorithmTags.CAMELLIA_256:
        return "Camellia";
    case SymmetricKeyAlgorithmTags.TWOFISH:
        return "Twofish";
    default:
        throw new IllegalArgumentException(....);
  }
}

В реальных проектах для различных case'ов возможны случаи, когда необходимо выполнить одинаковые действия. И для того, чтобы выглядело читабельнее, код можно написать более компактно:

public static String getSymmetricCipherName(int algorithm)
{
  switch (algorithm)
  {
    ....
    case SymmetricKeyAlgorithmTags.DES:
        return "DES";
    case SymmetricKeyAlgorithmTags.AES_128:
    case SymmetricKeyAlgorithmTags.AES_192:
    case SymmetricKeyAlgorithmTags.AES_256:
        return "AES";
    case SymmetricKeyAlgorithmTags.CAMELLIA_128:
    case SymmetricKeyAlgorithmTags.CAMELLIA_192:
    case SymmetricKeyAlgorithmTags.CAMELLIA_256:
        return "Camellia";
    case SymmetricKeyAlgorithmTags.TWOFISH:
        return "Twofish";
    default:
        throw new IllegalArgumentException(....);
  }
}

Рассмотрим пример из реального приложения, где разработчик допустил ошибку из-за опечатки:

protected boolean condition(Actor actor) throws ....
{
  ....
  if (fieldValue instanceof Number) 
  {
    ....
    switch (tokens[2]) 
    {
      case "=":
      case "==":
        passing = (Double) fieldValue
                  == 
                  Double.parseDouble(secondValue);
        break;
      case "!":
      case "!=":
        passing = (Double) fieldValue 
                  ==
                  Double.parseDouble(secondValue);
        break;
      case "<=":
        passing = ((Number) fieldValue).doubleValue() 
                  <=
                  Double.parseDouble(secondValue);
        break;
      ....
    }
   ....
  }
  ....
}

В коде меток '!' и '!=' допущена опечатка, которая возникла по всей видимости из-за copy-paste. Просмотрев остальные ветви case, можно прийти к выводу, что следовало использовать оператор сравнения '!=' вместо '=='.

Исправленный код:

protected boolean condition(Actor actor) throws ....
{
  ....
  if (fieldValue instanceof Number) 
  {
    ....
    switch (tokens[2]) 
    {
      case "=":
      case "==":
        passing = (Double) fieldValue
                  ==
                  Double.parseDouble(secondValue);
        break;
      case "!":
      case "!=":
        passing = (Double) fieldValue 
                  !=
                  Double.parseDouble(secondValue);
        break;
      case "<=":
        passing = ((Number) fieldValue).doubleValue() 
                  <=
                  Double.parseDouble(secondValue);
        break;
      ....
    }
   ....
  }
  ....
}

Найденные ошибки

Проверено проектов
354
Собрано ошибок
13 290

А ты совершаешь ошибки в коде?

Проверь с помощью
PVS-Studio

Статический анализ
кода для C, C++, C#
и Java

goto PVS-Studio;