Co to jest operacja &&& w 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;
}

Dane wyjściowe powyższego programu skompilowane przy użyciu gccto

0
1
1

Z opcją -Walllub wydaje ostrzeżenie:-Waddressgcc

warning: the address of i will always evaluate as true [-Waddress]

Jak cocenia się powyższy program?

manav mn
źródło
42
Wierzę, że to i && (&i)? Ciekawe, że nie mogę znaleźć duplikatu postu na SO.
irrelephant
42
while (i &&& i <-- j) {}.
kennytm,
8
Nie duplikat, ale podobne pytanie i to dobry link
Nathan Cooper,

Odpowiedzi:

272

Jest tak c = i && (&i);, ponieważ druga część jest zbędna, ponieważ &inigdy tego nie oceni false.

W przypadku typu zdefiniowanego przez użytkownika, w którym można faktycznie przeciążać jednoargumentowy operator &, może być inny, ale nadal jest to bardzo zły pomysł .

Jeśli włączysz ostrzeżenia , otrzymasz coś takiego:

ostrzeżenie: adres „i” zawsze będzie oceniany jako „prawda”

Luchian Grigore
źródło
1
Dlaczego nie c = i & (&&i);:; Gdzie ijest jakaś etykieta?
anishsane,
4
@anishsane ijest zdefiniowane jako inti w pytaniu nie ma etykiet. Również maksymalny munch ...
Luchian Grigore,
5
@anishsane: A &&operator, który ma wziąć adres etykiety, jest zresztą niestandardowym rozszerzeniem gcc. Ale nawet gdyby był to standard, reguła maksymalnego chrupnięcia uniemożliwiłaby jego analizę w ten sposób (chyba że wstawisz spację).
Keith Thompson
W rzeczywistości &imoże ocenić false. Jest czasem używany jako domyślny. Przykład: void fn(type& x = *reinterpret_cast<type*>(NULL)); Jaka jest wartość &xin, fnjeśli fnwywoływana jest bez parametrów? To 0 aka false. Jednak używając go w sposób opisany, zawsze będzie to prawdą, chyba że i == 0, i jeśli ktoś używałby go tak, jak opisałem, byłoby to możliwe c = &i && i.
Adrian
@LuchianGrigore: jak to?
Adrian
118

W &&&C. nie ma operatora ani tokena, ale operatory &&(logiczne i „) oraz &(jednoargumentowy lub bitowy” i „) istnieją.

Zgodnie z zasadą maksymalnego chrupania to:

c = i &&& i;

jest równoważne z tym:

c = i && & i;

Określa ona cdo 1 jeżeli oba ii &isą prawdziwe, a na 0, jeśli któreś z nich jest fałszywa.

W przypadku int każda niezerowa wartość jest prawdą. W przypadku wskaźnika każda wartość inna niż null jest prawdziwa (a adres obiektu jest zawsze różny od null). Więc:

Ustawia się cna 1, jeśli ijest niezerowe lub na 0if ijest równe zero.

Co oznacza, &&&że używa się go tutaj tylko do celowego zaciemniania. Przydziałem może być również dowolna z następujących czynności:

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
źródło