Nous utilisons des cookies pour améliorer votre expérience de navigation. En savoir plus
Accepter
to the top
close form

Remplissez le formulaire ci‑dessous en 2 étapes simples :

Vos coordonnées :

Étape 1
Félicitations ! Voici votre code promo !

Type de licence souhaité :

Étape 2
Team license
Enterprise licence
** En cliquant sur ce bouton, vous déclarez accepter notre politique de confidentialité
close form
Demandez des tarifs
Nouvelle licence
Renouvellement de licence
--Sélectionnez la devise--
USD
EUR
* En cliquant sur ce bouton, vous déclarez accepter notre politique de confidentialité

close form
La licence PVS‑Studio gratuit pour les spécialistes Microsoft MVP
close form
Pour obtenir la licence de votre projet open source, s’il vous plait rempliez ce formulaire
* En cliquant sur ce bouton, vous déclarez accepter notre politique de confidentialité

close form
I am interested to try it on the platforms:
* En cliquant sur ce bouton, vous déclarez accepter notre politique de confidentialité

close form
check circle
Votre message a été envoyé.

Nous vous répondrons à


Si vous n'avez toujours pas reçu de réponse, vérifiez votre dossier
Spam/Junk et cliquez sur le bouton "Not Spam".
De cette façon, vous ne manquerez la réponse de notre équipe.

>
>
>
V221. Suspicious sequence of types cast…
menu mobile close menu
Analyzer diagnostics
General Analysis (C++)
General Analysis (C#)
General Analysis (Java)
Micro-Optimizations (C++)
Diagnosis of 64-bit errors (Viva64, C++)
Customer specific requests (C++)
MISRA errors
AUTOSAR errors
OWASP errors (C#)
Problems related to code analyzer
Additional information
toggle menu Contents

V221. Suspicious sequence of types castings: pointer -> memsize -> 32-bit integer.

05 Mar 2015

This warning informs the programmer about the presence of a strange sequence of type conversions. A pointer is explicitly cast to a memsize-type and then again, explicitly or implicitly, to the 32-bit integer type. This sequence of conversions causes a loss of the most significant bits. It usually indicates a serious error in the code.

Take a look at the following example:

int *p = Foo();
unsigned a, b;
a = size_t(p);
b = unsigned(size_t(p));

In both cases, the pointer is cast to the 'unsigned' type, causing its most significant part to be truncated. If you then cast the variable 'a' or 'b' to a pointer again, the resulting pointer is likely to be incorrect.

The difference between the variables 'a' and 'b' is only in that the second case is harder to diagnose. In the first case, the compiler will warn you about the loss of the most significant bits, but keep silent in the second case as what is used there is an explicit type conversion.

To fix the error, we should store pointers in memsize-types only, for example in variables of the size_t type:

int *p = Foo();
size_t a, b;
a = size_t(p);
b = size_t(p);

There may be difficulties with understanding why the analyzer generates the warning on the following code pattern:

BOOL Foo(void *ptr)
{
  return (INT_PTR)ptr;
}

You see, the BOOL type is nothing but a 32-bit 'int' type. So we are dealing with a sequence of type conversions:

pointer -> INT_PTR -> int.

You may think there's actually no error here because what matters to us is only whether or not the pointer is equal to zero. But the error is real. It's just that programmers sometimes confuse the ways the types BOOL and bool behave.

Assume we have a 64-bit variable whose value equals 0x000012300000000. Casting it to bool and BOOL will have different results:

int64_t v = 0x000012300000000ll;

bool b = (bool)(v); // true

BOOL B = (BOOL)(v); // FALSE

In the case of 'BOOL', the most significant bits will be simply truncated and the non-zero value will turn to 0 (FALSE).

It's just the same with the pointer. When explicitly cast to BOOL, its most significant bits will get truncated and the non-zero pointer will turn to the integer 0 (FALSE). Although low, there is still some probability of this event. Therefore, code like that is incorrect.

To fix it, we can go two ways. The first one is to use the 'bool' type:

bool Foo(void *ptr)
{
  return (INT_PTR)ptr;
}

But of course it's better and easier to do it like this:

bool Foo(void *ptr)
{
  return ptr != nullptr;
}

The method shown above is not always applicable. For instance, there is no 'bool' type in the C language. So here's the second way to fix the error:

BOOL Foo(void *ptr)
{
  return ptr != NULL;
}

Keep in mind that the analyzer does not generate the warning when conversion is done over such data types as HANDLE, HWND, HCURSOR, and so on. Although these are in fact pointers (void *), their values always fit into the least significant 32 bits. It is done on purpose so that these handles could be passed between 32-bit and 64-bit processes. For details, see: How to correctly cast a pointer to int in a 64-bit application?