V206. Explicit conversion from 'void *' to 'int *'.
This warning informs you about an explicit conversion of the 'void *' or 'byte *' pointer to a function pointer or 32/64-bit integer pointer. Or vice versa.
Of course, the type conversion like that is not in itself an error. Let's figure out what for we have implemented this diagnostic.
It is a pretty frequent situation when a pointer to some memory buffer is passed into another part of the program through a void * or byte * pointer. There may be different reasons for doing so; it usually indicates a poor code design, but this question is out of the scope of this paper. Function pointers are often stored as void * pointers, too.
So, assume we have an array/function pointer saved as void * in some part of the program while it is cast back in another part. When porting such a code, you may get unpleasant errors: a type may change in one place but stay unchanged in some other place.
For example:
size_t array[20];
void *v = array;
....
unsigned* sizes = (unsigned*)(v);
This code works well in the 32-bit mode as the sizes of the 'unsigned' and 'size_t' types coincide. In the 64-bit mode, however, their sizes are different and the program will behave unexpectedly. See also pattern 6, changing an array type.
The analyzer will point out the line with the explicit type conversion where you will discover an error if study it carefully. The fixed code may look like this:
unsigned array[20];
void *v = array;
....
unsigned* sizes = (unsigned*)(v);
or like this:
size_t array[20];
void *v = array;
....
size_t* sizes = (size_t*)(v);
A similar error may occur when working with function pointers.
void Do(void *ptr, unsigned a)
{
typedef void (*PtrFoo)(DWORD);
PtrFoo f = (PtrFoo)(ptr);
f(a);
}
void Foo(DWORD_PTR a) { /*... */ }
void Call()
{
Do(Foo, 1);
}
The fixed code:
typedef void (*PtrFoo)(DWORD_PTR);
Note. The analyzer knows about the plenty of cases when explicit type conversion is safe. For instance, it doesn't worry about explicit type conversion of a void * pointer returned by the malloc() function:
int *p = (int *)malloc(sizeof(int) * N);
As said in the beginning, explicit type conversion is not in itself an error. That's why, despite numbers of exceptions to this rule, the analyzer still generates quite a lot of false V206 warnings. It doesn't know if there are any other fragments in the program where these pointers are used incorrectly, so it has to generate warnings on every potentially dangerous type conversion.
For instance, I've cited two examples of incorrect code and ways to fix them above. Even after they are fixed, the analyzer will keep generating false positives on the already correct code.
You can use the following approach to handle this warning: carefully study all the V206 messages once and then disable this diagnostic in the settings. If there are few false positives, use one of the false positive suppression methods.