Partager via


Avertissement du compilateur (niveau 2) C4146

unary minus operator applied to unsigned type, result still unsigned unsigned

Les types non signés ne peuvent contenir que des valeurs non négatives. Par conséquent, unaire moins (négation) n’a généralement pas de sens lorsqu’ils sont appliqués à un type non signé. L’opérande et le résultat ne sont pas négatifs.

Notes

Lorsque vous exprimez un littéral entier négatif, l’avant - de la valeur est analysée en tant qu’opérateur de négation unaire. Le compilateur applique l’opérateur après avoir analysé la valeur numérique. Si la valeur numérique correspond à la plage d’un type entier non signé, mais pas au type entier signé correspondant, le compilateur interprète la valeur comme non signée. Une valeur non signée est inchangée par l’opérateur de négation unaire.

Cet avertissement se produit souvent lorsque vous essayez d’exprimer la valeur minimale int , -2147483648 ou la valeur minimale long long , -9223372036854775808. Ces valeurs ne peuvent pas être écrites en tant que -2147483648 ou -9223372036854775808ll, respectivement. La raison est que le compilateur traite l’expression en deux étapes : d’abord, il analyse la valeur numérique, puis applique l’opérateur de négation. Par exemple, lorsque le compilateur analyse -2147483648, il suit les étapes suivantes :

  1. Le nombre 2147483648 est évalué. Étant donné qu’il est supérieur à la valeur maximale int de 2147483647, mais s’inscrit toujours dans un unsigned int, le type de 2147483648 est unsigned int.

  2. Unaire moins est appliqué à la valeur non signée, avec un résultat non signé, qui se produit également 2147483648.

Le type non signé du résultat peut entraîner un comportement inattendu. Si le résultat est utilisé dans une comparaison, une comparaison non signée peut être utilisée, par exemple lorsque l’autre opérande est un int.

Vous pouvez éviter L’utilisation INT_MIN ou LLONG_MIN l’équivalent <limits.h> C++ de C4146. <climits> Ces valeurs ont des types signés.

L’option /sdl du compilateur (Activer des vérifications de sécurité supplémentaires) élève cet avertissement à une erreur.

Exemple

L’exemple suivant illustre le comportement inattendu qui peut se produire lorsque le compilateur génère l’avertissement C4146 :

// C4146.cpp
// compile with: /W2
#include <iostream>

void check(int i)
{
    if (i > -9223372036854775808ll)   // C4146
        std::cout << i << " is greater than the most negative long long int.\n";
}

int main()
{
    check(-100);
    check(1);
}

Dans cet exemple, le compilateur considère -9223372036854775808ll non signé même si le littéral a un ll suffixe et que l’opérateur de négation est appliqué. Pour effectuer la < comparaison, le compilateur promeut silencieusement la signature i à unsigned long long int. La deuxième ligne attendue, 1 is greater than the most negative long long intn’est pas imprimée, car ((unsigned long long int)1) > 9223372036854775808ull elle a la valeur false.

Pour corriger l’exemple, incluez <climits> et remplacez -922337203685475808ll par LLONG_MIN.

Voir aussi

Opérateur de négation unaire (-)