# V646. The 'else' keyword may be missing. Consider inspecting the program's logic.

Оператор if расположен на той же строке, что и закрывающаяся скобка от предыдущего if. Возможно, в этом месте пропущено ключевое слово 'else' и программа работает не так, как ожидал программист.

Рассмотрим простой пример некорректного кода:

    if (A == 1) {
      Foo1(1);
    } if (A == 2) {
      Foo2(2);
    } else {
      Foo3(3);
    }

В случае если переменная 'A' принимает значение 1, то произойдет вызов не только функции 'Foo1', но и вызов функции 'Foo3'. Следует обратить внимание на логику выполнения программы, возможно так и должно быть. В случае ошибки следует добавить ключевое слово 'else'.

Корректный вариант кода:

    if (A == 1) {
      Foo1(1);
    } else if (A == 2) {
      Foo2(2);
    } else {
      Foo3(3);
    }

Так же корректным анализатор считает код, в котором в 'then' части первого условного оператора 'if' есть безусловный оператор 'return'. Поскольку в таком случае логика выполнения программы не нарушается, а присутствует только не совсем корректное форматирование кода. Пример такого кода:

    if (A == 1) {
      Foo1(1);
      return;
    } if (A == 2) {
      Foo2(2);
    } else {
      Foo3(3);
    }

Если ошибки нет, то устранить предупреждение V646 можно, если перенести оператор 'if' на следующую строку. Пример такого кода:

    if (A == 1) {
      Foo1(1);
    }
    if (A == 2) {
      Foo2(2);
    } else {
      Foo3(3);
    }

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

    if( 1 == (dst->nChannels) ) {
      ippiCopy_16s_C1MR((Ipp16s*)pDstCh, dstStep,
        (Ipp16s*)pDst, dst->widthStep, roi, pMask, roi.width);
    } if( 3 == (dst->nChannels) ) { //V646
      ippiCopy_16s_C3R((Ipp16s*)pDst-coi, dst->widthStep,
        (Ipp16s*)pTmp, dst->widthStep, roi);
      ippiCopy_16s_C1C3R((Ipp16s*)pDstCh, dstStep,
        (Ipp16s*)pTmp+coi, dst->widthStep, roi);
      ippiCopy_16s_C3MR((Ipp16s*)pTmp, dst->widthStep,
        (Ipp16s*)pDst-coi, dst->widthStep, roi, pMask, roi.width);
    } else {
      ippiCopy_16s_C4R((Ipp16s*)pDst-coi, dst->widthStep,
        (Ipp16s*)pTmp, dst->widthStep, roi);
      ippiCopy_16s_C1C4R((Ipp16s*)pDstCh, dstStep,
        (Ipp16s*)pTmp+coi, dst->widthStep, roi);
      ippiCopy_16s_C4MR((Ipp16s*)pTmp, dst->widthStep,
        (Ipp16s*)pDst-coi, dst->widthStep, roi, pMask, roi.width);
    }

Этот код очень сложен для чтения и понимания. Однако анализатор не теряет бдительности.

В данном примере условия '3 == (dst->nChannels)' и '1 == (dst->nChannels)' не могут выполниться одновременно, и форматирование кода указывает на пропущенное ключевое слово 'else'. Корректный вариант должен выглядеть следующим образом:

    if( 1 == (dst->nChannels) ) {
      ....
    } else if( 3 == (dst->nChannels) ) {
      ....
    } else {
      ....
    }

Данная диагностика классифицируется как:

CWE-670

Взгляните на примеры ошибок, обнаруженных с помощью диагностики V646.