Viva64 Send comments on this topic.
V107. Implicit type conversion NN argument of function 'FOO' to 32-bit type

Glossary Item Box

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:

  Copy image Copy Code
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 Viva64. 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:

  CopyCode image Copy 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;
}

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:

  CopyCode image Copy Code
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 Find incorrect explicit type conversion mode.

See also:

memsize type

limitations of the analyzer Viva64

implicit type conversion

explicit type conversion

how to find the explicit type conversion