V107. Implicit type conversion N argument of function 'foo' to 32-bit type.
The analyzer found a possible error related to the implicit conversion of the actual function argument which has memsize type to 32-bit type.
Let's examine an example of the code which contains the function for searching for the max array item:
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);
This code may work successfully on the 32-bit platform but it won't be able to process arrays containing more than 'INT_MAX' (2Gb) items on the 64-bit architecture. This limitation is caused by the use of int type for the argument 'arraySize'. Pay attention that the function code looks absolutely correct not only from the compiler's point of view but also from that of the analyzer. There is no type conversion in this function and one cannot find the possible problem.
The analyzer will warn about the implicit conversion of memsize type to a 32-bit type during the invocation of 'FindMaxItem' function. Let's try to find out why it happens so. According to C++ rules the result of the subtraction of two pointers has type 'ptrdiff_t'. When invocating 'FindMaxItem' function the implicit conversion of 'ptrdiff_t' type to 'int' type occurs which will cause the loss of the high bits. This may be the reason for the incorrect program behavior while processing a large data size.
The correct solution will be to replace 'int' type with 'ptrdiff_t' type for it will allow to keep the whole range of values. The corrected code:
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;
}
Analyzer tries as far as possible to recognize safe type conversions and keep from displaying warning messages on them. For example, the analyzer won't give a warning message on 'FindMaxItem' function's call in the following code:
float Arr[1000];
float maxValue =
FindMaxItem(Arr, sizeof(Arr)/sizeof(float));
When you are sure that the code is correct and the implicit type conversion of the actual function argument does not cause errors you may use the explicit type conversion so that to avoid showing warning messages. An example:
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);
In that case if you suspect that the code contains incorrect explicit conversions of memsize types to 32-bit types about which the analyzer does not warn, you may use the V202.
Additional materials on this topic:
- 64-bit Lessons. Lesson 17. Pattern 9. Mixed arithmetic.