# V779. Unreachable code was detected. It is possible that an error is present.

Анализатор обнаружил код, который никогда не будет выполнен. Возможно допущена ошибка в логике программы.

Данная диагностика находит блоки кода, до которых никогда не дойдёт управление.

Рассмотрим пример:

    void Error()
    {
      ....
      exit(1);
    }

    FILE* OpenFile(const char *filename)
    {
      FILE *f = fopen(filename, "w");
      if (f == nullptr)
      {
        Error();
        printf("No such file: %s", filename);
      }
      return f;
    }

Функция 'printf(....)' никогда не напечатает сообщение об ошибке, так как функция 'Error()' не возвращает управление. Как правильно исправить код зависит от того, какую логику поведения задумывал программист изначально. Возможно, функция должна возвращать управление. Возможно, нарушен порядок выражений и корректный код должен быть таким:

    FILE* OpenFile(const char *filename)
    {
      FILE *f = fopen(filename, "w");
      if (f == nullptr)
      {
        printf("No such file: %s", filename);
        Error();
      }
      return f;
    }

Рассмотрим ещё один пример:

    void f(char *s, size_t n)
    {
      for (size_t i = 0; i < n; ++i)
      {
        if (s[i] == '\0')
          break;
        else
          return;

        s[i] = toupper(s[i]);
      }
    }

Весь код, стоящий после 'if', не будет выполнен, так как обе ветви не возвращают управление. Скорее всего, нужно внести код в одну из ветвей или убрать noreturn выражение.

Например, можно исправить код следующим образом:

    void f(char *s, size_t n)
    {
      for (size_t i = 0; i < n; ++i)
      {
        if (s[i] == '\0')
          break;

        s[i] = toupper(s[i]);
      }
    }

Если реализация функции находится в другом файле, анализатору требуется подсказка, чтобы понять, что она всегда прекращает работу программы. В противном случае, он может не заметить ошибку. Для подсказки можно воспользоваться аннотациями при объявлении функции:

    [[noreturn]] void my_abort(); // C++11
    __declspec(noreturn) void my_abort(); // MSVC
    __attribute__((noreturn)) void my_abort(); // GCC

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

    int test()
    {
      throw 0;
      return 0;
    }

Это связано с тем, что такой код часто пишут для подавления предупреждений компилятора или других анализторов.

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

CWE-561 CERT-MSC12-C

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