﻿# V3152\. Potential division by zero\. Variable was compared to zero before it was used as a divisor\. Check lines: N1, N2\.

Анализатор обнаружил потенциальную ошибку, которая может привести к делению на ноль\.

Анализатор заметил в коде следующую ситуацию\. В начале вы сравниваете некоторое число с нулём, а потом делите на него уже без проверки\. Это может означать одно из двух:

1\) Возникнет ошибка, если число будет равно 0\.

2\) Программа всегда работает корректно, так как число всегда не равно 0\. Проверка является лишней\.

Рассмотрим первый вариант\. Здесь может возникнуть исключение\.

```cpp
int num = Foo();
if (num != 0)
  variable1 = 3 / num;
variable2 = 5 / num;
```

Если значение переменной 'num' окажется равно нулю, то выполнение выражения '5 / num ' приведёт к ошибке\. Анализатор выдаст предупреждение на этот код, указав на 2 строки\. Первая строка \- это то место, где происходит деление на переменную\. Вторая строка \- это то место, где переменная сравнивается с нулём\.

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

```cpp
int num = Foo();
if (num != 0) 
{
  variable1 = 3 / num;
  variable2 = 5 / num;
}
```

Рассмотрим второй вариант\. Деление безопасное, проверка лишняя:

```cpp
List<string> list = CreateNonEmptyList();
var count = list.Count;
if (count == 0) {....}
var variable = 10 / count;
```

Предположим, что метод 'CreateNonEmptyList' возвращает список 'list' всегда с ненулевым числом элементов\. Тогда приведённый выше код всегда будет работать корректно, а деления на 0 никогда не случится 

**Примечание:** в данном примере не всегда будет сгенерировано предупреждение V3152 \- если анализатор сможет понять, что данный метод возвращает всегда непустой список, то он выдаст на проверку 'list\.Count \=\= 0' предупреждение V3022 "данное выражение всегда истинно"\. Если не сможет \(например, из\-за сложной последовательности переприсвоений переменных, когда этот метод виртуальный, и т\.п\.\) \- будет сгенерировано предупреждение V3152\. Тип сгенерированного предупреждения будет зависеть от реализации метода 'CreateNonEmptyList'\.

Чтобы предупреждение исчезло, можно удалить проверку 'if \(list \=\= null \|\| list\.Count \=\= 0\)'\. В данном случае она не имеет практического смысла и может только запутать программиста, читающего код\.

Исправленный вариант:

```cpp
List<string> list = CreateNonEmptyList();
var variable = 10 / list.Count;
```

Ещё один вариант сообщения анализатора \- когда проверка и использование расположены в разных ветках if\\else или switch выражений\. Например:

```cpp
if (lines.Count == 1)
{
  if (num != 0)
    variable = 10 / num;
}
else
{
  variable = 10 / num;
}
```

В такой ситуации, несмотря на то что обе ветки никогда не выполняются одновременно, а будет выбрана только одна из веток, сравнение с нулём в одной из них косвенно свидетельствует о возможности принятия переменной значения ноль и в другой ветке\. Тогда, если управление придёт во вторую ветку, произойдёт деление на ноль\.

Исправленный вариант:

```cpp
if (lines.Count == 1)
{
  if (num != 0)
    variable = 10 / num;
}
else
{
  if (num != 0)
    variable = 10 / num;
}
```

В случае если анализатор ошибается, то кроме изменения кода, можно использовать комментарий для подавления предупреждений\. Например: 

```cpp
variable = 10 / num; //-V3152
```