símbolos - |= c




O que faz o C ??! ?? operador faz? (3)

É um trigraph C. ??! é | , então ??!??! é o operador ||

Eu vi uma linha de C que se parecia com isso:

!ErrorHasOccured() ??!??! HandleError();

É compilado corretamente e parece rodar ok. Parece que está verificando se um erro ocorreu e, se tiver, ele o manipula. Mas eu não tenho certeza do que está realmente fazendo ou como está sendo feito. Parece que o programador está tentando expressar seus sentimentos sobre erros.

Eu nunca vi o ??!??! antes em qualquer linguagem de programação, e não consigo encontrar documentação para isso em nenhum lugar. (O Google não ajuda com termos de pesquisa como ??!??! ). O que faz e como funciona o exemplo de código?


Bem, por que isso existe em geral é provavelmente diferente do por que existe em seu exemplo.

Tudo começou há meio século atrás com o reaproveitamento de terminais de comunicação impressos como interfaces de usuário de computador. Na era Unix e C inicial, esse era o Teletipo ASR-33.

Este dispositivo era lento (10 cps) e barulhento e feio e sua visão do conjunto de caracteres ASCII terminava em 0x5f, então ele tinha (observe atentamente a foto) nenhuma das teclas:

{ | } ~ 

Os trigramas foram definidos para corrigir um problema específico. A idéia era que os programas em C poderiam usar o subconjunto ASCII encontrado no ASR-33 e em outros ambientes sem os altos valores ASCII.

Seu exemplo é na verdade dois de ??! , each significado | , então o resultado é || .

No entanto, as pessoas que escreviam código C quase por definição tinham equipamentos modernos, 1 então, meu palpite é: alguém se exibindo ou divertindo-se, deixando uma espécie de ovo de páscoa no código para você encontrar.

Com certeza funcionou, levou a uma pergunta SO tão popular.

Teletipo ASR-33

1. Aliás, os trigraphs foram inventados pelo comitê ANSI, que se reuniu pela primeira vez depois que o C se tornou um grande sucesso, então nenhum dos codificadores ou codificadores C originais os usaria.


??! é um trigraph que se traduz em | . Então diz:

!ErrorHasOccured() || HandleError();

que, devido a curto-circuito, é equivalente a:

if (ErrorHasOccured())
    HandleError();

Guru da Semana (lida com C ++, mas relevante aqui), onde eu peguei isso.

Possível origem de trigramas ou como @DwB aponta nos comentários é mais provável devido a EBCDIC ser difícil (novamente). This discussão na placa IBM developerworks parece suportar essa teoria.

De ISO / IEC 9899: 1999 §5.2.1.1, nota de rodapé 12 (h / t @ Random832):

As seqüências de trigramas permitem a entrada de caracteres que não estão definidos no conjunto de códigos invariantes, conforme descrito na ISO / IEC 646, que é um subconjunto do conjunto de códigos ASCII US de sete bits.





trigraphs