Domanda

ho visto una fila di C che si presentava così:

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

E 'stato compilato correttamente e sembra funzionare bene. Sembra come se fosse controllare se si è verificato un errore, e se ha, esso gestisce. Ma io non sono davvero sicuro di quello che sta effettivamente facendo o come sta facendo. Lo fa apparire come il programmatore sta cercando esprimere i loro sentimenti sugli errori.

Non ho mai visto la ??!??! prima che in qualsiasi linguaggio di programmazione, e non riesco a trovare la documentazione per esso ovunque. (Google non aiuta con i termini di ricerca come ??!??!). Che cosa fa e come funziona il codice di esempio?

È stato utile?

Soluzione

??! è un href="http://en.wikipedia.org/wiki/Digraphs_and_trigraphs#C" rel="noreferrer"> trigraph che si traduce in |. Così si dice:

!ErrorHasOccured() || HandleError();

che, a causa di corto circuito, è equivalente a:

if (ErrorHasOccured())
    HandleError();

Guru della settimana (si occupa di C ++ ma rilevanti qui), dove ho preso questo in su.

Possibile origine di trigraph o come sottolinea @DwB nei commenti è più probabile a causa di EBCDIC essere difficile (di nuovo). Questa discussione su IBM developerWorks bordo sembra supportare questa teoria.

Da ISO / IEC 9899: 1999 §5.2.1.1, nota 12 (h / t @ Random832):

Le sequenze trigraph consentono l'immissione di caratteri che non sono definite nel Set codice invariante descritto nella norma ISO / IEC 646, che è un sottoinsieme dei sette bit US set di codice ASCII.

Altri suggerimenti

Bene, perché questa esiste, in generale, è probabilmente diverso da quello per cui esiste nel tuo esempio.

Tutto è iniziato mezzo secolo fa, con la riproposizione terminali di comunicazione cartacei come interfacce utente del computer. Nell'era iniziale di Unix e C, che è stato l'ASR-33 Teletype.

Questo dispositivo è stato lento (10 cps) e rumoroso e brutto e la sua vista del set di caratteri ASCII chiuso al 0x5f, quindi aveva (un'occhiata da vicino al pic) nessuna delle chiavi:

{ | } ~ 

Il trigrammi sono state definite per risolvere un problema specifico. L'idea era che i programmi C potrebbero utilizzare il sottoinsieme ASCII trovati sul ASR-33 e in altri ambienti mancanti i valori di alta ASCII.

Il vostro esempio è in realtà due di ??!, ogni | senso, quindi il risultato è ||.

Tuttavia, le persone che scrivono codice C quasi per definizione avevano attrezzature moderne, 1 così la mia ipotesi è: qualcuno in mostra o divertirsi themself, lasciando una sorta di uovo di Pasqua in il codice per voi per trovare.

E 'sicuro ha funzionato, ha portato ad una domanda così selvaggiamente popolare.

 ASR-33 Teletype

ASR-33 Teletype


1. Del resto, i trigrammi sono stati inventati dal comitato ANSI, che per primo ha incontrato dopo C diventare un successo travolgente, così nessuno di codice C originale o codificatori li avrebbe utilizzati.

E 'un C trigraph . ??! è |, così ??!??! è il || operatore

??!??! Come già indicato è essenzialmente due trigraphs ( ??! e ??! nuovo) mushed insieme che vengono sostituiti-tradotto a ||, ossia la OR logico , dal preprocessore.

La tabella che segue contiene tutti i trigraph dovrebbe aiutare combinazioni alternano trigraph disambiguare:

Trigraph   Replaces

??(        [
??)        ]
??<        {
??>        }
??/        \
??'        ^
??=        #
??!        |
??-        ~

Fonte: C: Manuale di riferimento A 5th Edition

Quindi un trigraph che assomiglia ??(??) finiranno per mappare [], ??(??)??(??) otterrà sostituito da [][] e così via, si ottiene l'idea.

Dal trigrammi vengono sostituiti durante la pre-elaborazione è possibile utilizzare cpp per ottenere una vista dell'uscita da soli, utilizzando un programma trigr.c sciocca:

void main(){ const char *s = "??!??!"; } 

e l'elaborazione con:

cpp -trigraphs trigr.c 

Si otterrà un output della console di

void main(){ const char *s = "||"; }

Come si può notare, l'-trigraphs opzione deve essere specificata oppure cpp emetterà un avviso; questo indica come trigrammi sono una cosa del passato e di nessun valore moderno diverso da confondere le persone che potrebbero imbattersi in loro .


Per quanto riguarda la logica dietro l'introduzione di trigrammi, si comprende meglio se si guarda la sezione di storia di ISO / IEC 646 :

ISO / IEC 646 e il suo predecessore ASCII (ANSI X3.4) in gran parte approvato pratiche esistenti per quanto riguarda la codifica dei caratteri nel settore delle telecomunicazioni.

come ASCII non ha fornito un certo numero di caratteri necessari per le lingue diverse dall'inglese, una serie di varianti nazionali sono state fatte che sostituito alcuni caratteri meno usati con quelli necessari .

(sottolineatura mia)

Quindi, in sostanza, alcuni caratteri necessari (quelli per i quali esiste un trigraph) sono stati sostituiti in certe varianti nazionali. Questo porta alla rappresentazione alternativa usando trigraphs compresi di caratteri che altre varianti avevano ancora dintorni.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top