Qu'est-ce que le &&& opération en C

195
#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 gccest

0
1
1

Avec l' option -Wallou -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?

manav mn
la source
42
Je crois que c'est i && (&i)? Intéressant que je ne trouve pas un article en double sur SO.
irrelephant
42
while (i &&& i <-- j) {}.
kennytm
8
Pas un doublon, mais une question similaire et c'est un bon lien
Nathan Cooper

Réponses:

272

C'est c = i && (&i);, avec la deuxième partie étant redondante, car &ine sera jamais évaluée false.

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:

avertissement: l'adresse de «i» sera toujours évaluée comme «vraie»

Luchian Grigore
la source
1
Pourquoi pas c = i & (&&i);:; Où iest une étiquette?
anishsane
4
@anishsane iest défini comme intet il n'y a pas d'étiquettes dans la question. Aussi, munch maximal ...
Luchian Grigore
5
@anishsane: Et l' &&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).
Keith Thompson
En fait, &ipeut évaluer false. Il est parfois utilisé pour les valeurs par défaut. Exemple: void fn(type& x = *reinterpret_cast<type*>(NULL)); Quelle est la valeur de &xin fnsi fnest appelé sans paramètres? C'est 0 aka faux. Cependant, en l'utilisant de la manière décrite, ce sera toujours vrai à moins que i == 0, et si l'on l'utilisait comme je l'ai décrit, ce serait le cas c = &i && i.
Adrian
@LuchianGrigore: comment cela?
Adrian
118

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:

c = i &&& i;

est équivalent à ceci:

c = i && & i;

Il prend la valeur c1 si les deux iet &isont 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 c1 si différent de izéro ou 0si iest é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:

c = i && 1;
c = !!i;
c = (bool)i;          // C++ or C with <stdbool.h>
c = i ? 1 : 0;        /* C */
c = i ? true : false; // C++
Keith Thompson
la source