>
>
>
V591. Non-void function must return val…


V591. Non-void function must return value.

Анализатор обнаружил non-void функцию, для которой существует путь исполнения, не возвращающий значение. Вызов такой функции ведёт к неопределённому поведению.

Если при исполнении тела non-void функции достигнут конец её тела без 'return', то произойдёт неопределённое поведение.

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

int GetSign(int arg)
{
  if (arg > 0)
  {
    return 1;
  }
  else if (arg < 0)
  {
    return -1;
  }
}

Если в функцию 'GetSign' передать 0, то произойдёт неопределённое поведение. Исправленный вариант:

int GetSign(int arg)
{
  if (arg > 0)
  {
    return 1;
  }
  else if (arg < 0)
  {
    return -1;
  }

  return 0;
}

Исключением из правила являются функции 'main' и 'wmain'. Для этих функций достижение конца тела эквивалентно выполнению конструкции 'return 0;', поэтому неопределённого поведения не будет. Рассмотрим такой пример:

....
int main()
{
  AnalyzeFile(FILE_NAME);
}

В данном случае имеем дело с функцией 'main'. Здесь не будет неопределённого поведения. Соответственно, не будет и выдано предупреждение анализатора. Фрагмент кода эквивалентен следующему:

....
int main()
{
  AnalyzeFile(FILE_NAME);
  return 0;
}

Заметим, что неопределённое поведение происходит, только если конец non-void функции действительно достигнут. В частности, если на пути исполнения тела такой функции произошёл бросок исключения, которое не было перехвачено в теле этой же функции, то неопределённого поведения не будет.

Анализатор не выдаст предупреждение на следующем фрагменте кода:

int Calc(int arg);

int Bar(int arg)
{
  if (arg > 0)
  {
    return Calc(arg);
  }
  throw std::logic_error { "bad arg was passed to Bar" };
}

Также неопределённого поведения не будет, если в ходе выполнения тела такой функции произошел вызов другой функции, которая не возвращает управление. Такие функции обычно помечают '[[noreturn]]'. Поэтому анализатор не выдаст предупреждение на следующем примере:

[[noreturn]] void exit(int exit_code);

int Foo()
{
  ....
  exit(10);
}

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

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