En C et C++, dans la grande majorité des cas, le type d'une expression est déterminé à partir de l'expression elle-même, sans tenir compte du contexte dans lequel elle apparaît.
int var = 5u - 10;
5u
est de type unsigned int
; 10
est de type int
. Les règles de l'opérateur -
provoquent la conversion de l'argument int
en unsigned int
, ce qui rend l'expression équivalente à 5u - 10u
. Le résultat est UINT_MAX + 1 - 10
, un très grand nombre. L'initialisation convertit implicitement cela de unsigned int
à signed int
. Puisque cette valeur (presque certainement) n'est pas représentable comme int
, le résultat de la conversion est défini par l'implémentation. Dans presque toutes les implémentations existantes, la conversion réinterprète simplement la représentation non signée comme s'il s'agissait d'une valeur signée, aboutissant à -5
. (Ceci s'applique aux systèmes qui utilisent une représentation en complément à deux pour les valeurs négatives, la simplicité résultante des conversions signées/non signées est l'une des raisons pour lesquelles le complément à deux est si largement utilisé.)
Notez qu'il ne serait pas possible de var
pour avoir la valeur 4294967291
; la plus grande valeur qu'un int
peut contenir sur votre système est (probablement) 2147483647
.
auto var = 5u - 10;
5u - 10
est évalué de la même manière que précédemment, ce qui un résultat unsigned int
de UINT_MAX + 1 - 5
ou 4294967291
sur votre système. Le auto
signifie que var
prend le type de l'expression, unsigned int
, donc aucune conversion n'est effectuée. (Sur un système 16 bits int
, le résultat serait 65531
.)
En réponse à votre question, la 10
constante est converti de int
à unsigned int
dans les deux cas.
'5u - 10' évalue à un' non signé 'selon C Standard. – sgarizvi
C ou C++? Choisissez-en un. –
Le résultat de la soustraction est 'unsigned' dans les deux cas, mais dans le premier cas, le résultat est converti en type de destination. Par conséquent '4294967291' est converti en' -5' – Praetorian