# V107. Implicit type conversion N argument of function 'foo' to 32-bit type.

Анализатор обнаружил потенциально возможную ошибку, связанную с неявным приведением фактического аргумента функции, имеющего тип memsize к 32-битному типу.

Рассмотрим пример кода, в котором реализована функция поиска максимального элемента в массиве:

    float FindMaxItem(float *array, int arraySize) {
      float max = -FLT_MAX;
      for (int i = 0; i != arraySize; ++i) {
        float item = *array++;
        if (max < item)
          max = item;
      }
      return max;
    }
    ...
    float *beginArray;
    float *endArray;
    float maxValue = FindMaxItem(beginArray, endArray - beginArray);

Данный код успешно может работать на 32-битной платформе, но не сможет обрабатывать массивы, состоящие более чем из 'INT_MAX' (2Гб) элементов на 64-битной архитектуре. Это ограничение вызвано использованием типа 'int' для аргумента 'arraySize'. Обратите внимание, что код функции выглядит совершенно корректно не только с точки зрения компилятора, но и анализатора. В этой функции отсутствует приведение типов, и невозможно выявить потенциальную проблему.

Анализатор предупредит о неявном приведении memsize типа к 32-битному типу при вызове функции 'FindMaxItem'. Попробуем разобраться, почему это происходит. Согласно правилам языка Си++, результат вычитания одного указателя из другого имеет тип 'ptrdiff_t'. При вызове функции 'FindMaxItem' произойдет неявное приведение типа 'ptrdiff_t' к типу 'int', в результате чего произойдет потеря старших битов. Это может стать причиной некорректного поведения программы, при обработке большого объема данных.

Правильным решением будет заменить тип 'int' на тип 'ptrdiff_t', так как он позволит хранить весь диапазон допустимых значений. Исправленный код:

    float FindMaxItem(float *array, ptrdiff_t arraySize) {
      float max = -FLT_MAX;
      for (ptrdiff_t i = 0; i != arraySize; ++i) {
        float item = *array++;
        if (max < item)
          max = item;
      }
      return max;
    }

Анализатор по возможности старается распознать безопасные приведения типов и не выдавать на них предупреждения. Например, анализатор не выдаст предупреждение на вызов функции FindMaxItem в следующем коде:

    float Arr[1000];
    float maxValue =
       FindMaxItem(Arr, sizeof(Arr)/sizeof(float));

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

    extern int nPenStyle
    extern size_t nWidth;
    extern COLORREF crColor;
    ...
    // Call constructor CPen::CPen(int, int, COLORREF)
    CPen myPen(nPenStyle, static_cast<int>(nWidth), crColor);

В том случае, если вы подозреваете наличие в своем коде некорректных явных приведений memsize типов к 32-битным типам, на которые анализатор не выдает предупреждения, то вы можете воспользоваться правилом V202.

Дополнительные материалы по данной теме:

- 64-битные уроки. Урок 17. Паттерн 9. Смешанная арифметика.