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. Смешанная арифметика.