O que é &&& operação em 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;
}

A saída do programa acima compilado usando gccé

0
1
1

Com a opção -Wallou -Waddress, gccemite um aviso:

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

Como está csendo avaliado no programa acima?

manav mn
fonte
42
Eu acredito que é i && (&i)? Interessante não encontrar uma postagem duplicada no SO.
23412
42
while (i &&& i <-- j) {}.
Kennytm
8
Não é um duplicado, mas sa pergunta semelhante e isso é um link bom
Nathan Cooper

Respostas:

272

É c = i && (&i);, com a segunda parte sendo redundante, pois &inunca será avaliada false.

Para um tipo definido pelo usuário, onde você pode sobrecarregar unário operator &, pode ser diferente, mas ainda é uma péssima idéia .

Se você ativar os avisos , receberá algo como:

aviso: o endereço de 'i' sempre será avaliado como 'verdadeiro'

Luchian Grigore
fonte
1
Por que não c = i & (&&i);:; Onde iestá algum rótulo?
anishsane
4
@anishsane ié definido como inte não há rótulos na pergunta. Além disso, máxima mastigação ...
Luchian Grigore
5
@anishsane: E o &&operador para pegar o endereço de uma etiqueta é uma extensão gcc não-padrão de qualquer maneira. Mas, mesmo que fosse padrão, a regra munch máxima impediria que ela fosse analisada dessa maneira (a menos que você insira um espaço).
Keith Thompson
Na verdade, &ipode avaliar a false. Às vezes é usado para padrões. Exemplo: void fn(type& x = *reinterpret_cast<type*>(NULL)); Qual é o valor de &xin fnse fné chamado sem parâmetros? É 0, também conhecido como falso. No entanto, usá-lo da maneira descrita, sempre será verdade i == 0, a menos que , e se alguém o estivesse usando como eu descrevi, seria c = &i && i.
Adrian
@LuchianGrigore: como assim?
Adrian
118

Não há &&&operador ou token em C. Mas os operadores &&(lógico "e") e &(endereço unário ou bit a bit "e") existem.

Pela regra munch máxima , isto:

c = i &&& i;

é equivalente a isso:

c = i && & i;

Ele define c1 se ambos ie &iforem verdadeiros e 0 se um deles for falso.

Para um int, qualquer valor diferente de zero é verdadeiro. Para um ponteiro, qualquer valor não nulo é verdadeiro (e o endereço de um objeto é sempre não nulo). Assim:

Ele define ccomo 1 se ifor diferente de zero ou 0se ifor igual a zero.

O que implica que o item &&&está sendo usado aqui apenas para ofuscação deliberada. A atribuição também pode ser uma das seguintes:

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
fonte