#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é en utilisant gcc
est
0
1
1
Avec l' option -Wall
ou -Waddress
, gcc
émet un avertissement:
warning: the address of ‘i’ will always evaluate as ‘true’ [-Waddress]
Comment est c
évalué dans le programme ci-dessus?
c++
c
operators
compiler-optimization
gcc-warning
manav mn
la source
la source
i && (&i)
? Intéressant que je ne trouve pas un article en double sur SO.while (i &&& i <-- j) {}
.Réponses:
C'est
c = i && (&i);
, avec la deuxième partie étant redondante, car&i
ne sera jamais évaluéefalse
.Pour un type défini par l'utilisateur, où vous pouvez réellement surcharger unaire
operator &
, cela peut être différent, mais c'est toujours une très mauvaise idée .Si vous activez les avertissements , vous obtiendrez quelque chose comme:
la source
c = i & (&&i);
:; Oùi
est une étiquette?i
est défini commeint
et il n'y a pas d'étiquettes dans la question. Aussi, munch maximal ...&&
opérateur de prendre l'adresse d'une étiquette est de toute façon une extension gcc non standard. Mais même si elle était standard, la règle du grignotage maximal l'empêcherait d'être analysée de cette façon (sauf si vous insérez un espace).&i
peut évaluerfalse
. Il est parfois utilisé pour les valeurs par défaut. Exemple:void fn(type& x = *reinterpret_cast<type*>(NULL));
Quelle est la valeur de&x
infn
sifn
est appelé sans paramètres? C'est 0 aka faux. Cependant, en l'utilisant de la manière décrite, ce sera toujours vrai à moins quei == 0
, et si l'on l'utilisait comme je l'ai décrit, ce serait le casc = &i && i
.Il n'y a ni
&&&
opérateur ni jeton en C. Mais les opérateurs&&
(logique "et") et&
(adresse unaire ou bit à bit "et") existent.Selon la règle du grignotage maximal , ceci:
est équivalent à ceci:
Il prend la valeur
c
1 si les deuxi
et&i
sont vrais, et 0 si l'un d'eux est faux.Pour un entier, 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 prend la valeur
c
1 si différent dei
zéro ou0
sii
est égal à zéro.Ce qui implique que le
&&&
est utilisé ici uniquement pour un obscurcissement délibéré. La mission pourrait également être l'une des suivantes:la source