#include<stdio.h>
int main() {
     int x = 0x80000000;
     printf("%i\n",(((x - 1) >> 31) & 1));  //shows 0 as output
     printf("%i\n",!(((x - 1) >> 31) & 1));  //shows 0 as output(expected 1)
}

Pourquoi cela arrive-t-il? Comme les deux instructions effectuent la même opération à l'exception du ! opérateur. Pourquoi le deuxième printf ne donne-t-il pas 1 en sortie? D'après ce que je sais, une logique non supérieure à 0 donne 1 et une logique non supérieure à d'autres nombres donne 0. Est-ce que je fais quelque chose de mal ici ?

2
Mr_Arrow 15 oct. 2020 à 06:12

1 réponse

Meilleure réponse

Ce que vous voyez ici est une manifestation d'un comportement indéfini causé par un débordement d'entier signé.

En supposant un int de 32 octets utilisant le complément à deux, la valeur 0x80000000 est en dehors de la plage de int, elle subit donc une conversion définie par l'implémentation. Très probablement, il se convertit en la valeur -2147483648 qui est la valeur minimale pouvant être conservée dans un int sur votre système.

La prochaine chose que vous faites dans les deux cas est de soustraire 1 de cette valeur. Ceci n'est pas garanti. Ceci est considéré comme un débordement et est un comportement indéfini. C'est pourquoi vous voyez les résultats que vous voyez. Une fois que vous avez un comportement indéfini, il n'y a aucune garantie de ce que le programme fera.

3
dbush 15 oct. 2020 à 03:22