#include <stdio.h>
volatile int i;
int main()
{
int c;
for (i = 0; i < 3; i++)
{
c = i &&& i;
printf("%d\n", c);
}
return 0;
}
La sortie du programme ci-dessus compilé à l'aide de gcc
est
0
1
1
Avec le -Wall
ou -Waddress
option, gcc
émet un avertissement:
warning: the address of ‘i’ will always evaluate as ‘true’ [-Waddress]
Comment c
est-il évalué dans le programme ci-dessus?
C'est c = i && (&i);
, la deuxième partie étant redondante, puisque &i
n'évaluera jamais en false
.
Pour un type défini par l'utilisateur, où vous pouvez réellement surcharger unaire operator &
, ça pourrait être différent, mais c'est quand même un très mauvaise idée.
Si vous activez les avertissements, vous obtiendrez quelque chose comme:
avertissement: l'adresse de "i" sera toujours considérée comme "vraie"
Il n'y a pas d'opérateur &&&
Ou de jeton en C. Mais les opérateurs &&
(Logique "et") et &
(Adresse unaire ou bit à bit "et") existent .
Par la règle munch maximal , ceci:
c = i &&& i;
est équivalent à ceci:
c = i && & i;
Il définit c
à 1 si les deux i
et &i
Sont vrais, et à 0 si l'un d'eux est faux.
Pour un int, toute valeur non nulle est vraie. Pour un pointeur, toute valeur non nulle est vraie (et l'adresse d'un objet est toujours non nulle). Alors:
Il définit c
à 1 si i
est différent de zéro, ou à 0
Si i
est égal à zéro.
Ce qui implique que le &&&
Est utilisé ici uniquement pour une obfuscation délibérée. La mission pourrait également être l'une des suivantes:
c = i && 1;
c = !!i;
c = (bool)i; // C++ or C with <stdbool.h>
c = i ? 1 : 0; /* C */
c = i ? true : false; // C++