V103. Implicit type conversion from memsize type to 32-bit type.
The analyzer found a possible error related to the implicit memsize-type conversion to 32-bit type. The error consists in the loss of high bits in 64-bit type which causes the loss of the value.
The compiler also diagnoses such type conversions and shows warnings. Unfortunately, such warnings are often switched off, especially when the project contains a great deal of the previous legacy code or old libraries are used. In order not to make a programmer look through hundreds and thousands of such warnings, showed by the compiler, the analyzer informs only about those which may be the cause of the incorrect work of the code on the 64-bit platform.
The first example.
Our application works with videos and we want to calculate what file-size we'll need in order to store all the shots kept in memory into a file.
size_t Width, Height, FrameCount; ... unsigned BufferSizeForWrite = Width * Height * FrameCount * sizeof(RGBStruct);
Earlier the general size of the shots in memory could never excess 4 Gb (practically 2-3 Gb depending on the kind of OS Windows). On the 64-bit platform we have an opportunity to store much more shots in memory, and let's suppose that their general size is 10 Gb. After putting the result of the expression "Width * Height * FrameCount * sizeof(RGBStruct)" into the variable 'BufferSizeForWrite', we'll truncate high bits and will deal with the incorrect value.
The correct solution will be to change the type of the variable 'BufferSizeForWrite' into type 'size_t'.
size_t Width, Height, FrameCount; ... size_t BufferSizeForWrite = Width * Height * FrameCount * sizeof(RGBStruct);
The second example.
Saving of the result of pointers subtraction.
char *ptr_1, *ptr_2; ... int diff = ptr_2 - ptr_1;
If pointers differ more than in one 'INT_MAX' byte (2 Gb) a value cutoff during the assignment will occur. As a result the variable 'diff' will have an incorrect value. For the storing of the given value we should use type 'ptrdiff_t' or another memsize type.
char *ptr_1, *ptr_2; ... ptrdiff_t diff = ptr_2 - ptr_1;
When you are sure about the correctness of the code and the implicit type conversion does not cause errors while changing over to the 64-bit platform, you may use the explicit type conversion in order to avoid error messages showed in this line. For example:
unsigned BitCount = static_cast<unsigned>(sizeof(RGBStruct) * 8);
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 can use the V202.
As was said before analyzer informs only about those type conversions which can cause incorrect code work on a 64-bit platform. The code given below won't be considered incorrect though there occurs conversion of memsize type to int type:
int size = sizeof(float);
Additional materials on this topic:
- 64-bit Lessons. Lesson 17. Pattern 9. Mixed arithmetic.