Frage Was macht das C ??! ??! Betreiber tun?


Ich sah eine Linie von C, die so aussah:

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

Es kompiliert korrekt und scheint in Ordnung zu sein. Es scheint, als ob es überprüft, ob ein Fehler aufgetreten ist, und wenn es ist, behandelt es es. Aber ich bin mir nicht sicher, was es eigentlich macht oder wie es geht. Es sieht so aus, als ob der Programmierer versucht, seine Gefühle über Fehler auszudrücken.

Ich habe das nie gesehen ??!??! vorher in irgendeiner Programmiersprache, und ich kann nirgendwo Dokumentation dafür finden. (Google hilft nicht bei Suchbegriffen wie ??!??!). Was macht es und wie funktioniert das Codebeispiel?


1603
2017-10-19 16:56


Ursprung


Antworten:


??! ist ein Trigraph das übersetzt in |. So heißt es:

!ErrorHasOccured() || HandleError();

was aufgrund eines Kurzschlusses entspricht:

if (ErrorHasOccured())
    HandleError();

Guru der Woche (befasst sich mit C ++ aber relevant hier), wo ich das aufgenommen habe.

Möglicher Ursprung von Trigraphen oder wie @DwB in den Kommentaren darauf hinweist, ist es wahrscheinlicher, dass EBCDIC (wieder) schwierig ist. Dies Die Diskussion auf dem IBM Entwicklerworks Board scheint diese Theorie zu unterstützen.

Aus ISO / IEC 9899: 1999 §5.2.1.1, Fußnote 12 (h / t @ Random832):

Die Trigraph-Sequenzen ermöglichen die Eingabe von Zeichen, die im Invariant Code Set nicht definiert sind   beschrieben in ISO / IEC 646, die eine Teilmenge des Sieben-Bit-US-ASCII-Code-Satzes ist.


1319
2017-10-19 16:58



Nun, warum das im Allgemeinen existiert, ist wahrscheinlich anders als warum es in Ihrem Beispiel existiert.

Alles begann vor einem halben Jahrhundert mit der Umnutzung von Hardcopy-Kommunikationsendgeräten als Computer-Benutzerschnittstellen. In der ersten Unix- und C-Ära war das der ASR-33 Teletype.

Dieses Gerät war langsam (10 cps) und laut und hässlich und seine Sicht auf den ASCII-Zeichensatz endete bei 0x5f, also hatte es (siehe genaues Bild) keine der Tasten:

{ | } ~ 

Die Trigraphen wurden definiert, um ein spezifisches Problem zu beheben. Die Idee war, dass C-Programme die ASCII-Teilmenge verwenden konnten, die auf der ASR-33 gefunden wurde, und in anderen Umgebungen die hohen ASCII-Werte fehlten.

Ihr Beispiel ist eigentlich zwei von ??!, jede Bedeutung |, so ist das Ergebnis ||.

Jedoch hatten Leute, die C-Code fast per Definition schreiben, moderne Ausrüstung,1 also meine Vermutung ist: jemand, der sich zeigt oder sich amüsiert, eine Art Osterei im Code hinterlassen, damit du es findest.

Es hat sicher funktioniert, es hat zu einer sehr populären SO Frage geführt.

ASR-33 Teletype

ASR-33 Fernschreiber


1. Zu diesem Zweck wurden die Trigraphen vom ANSI-Komitee erfunden, das sich zuerst traf nach C wurde zu einem außer Kontrolle geratenen Erfolg, so dass keiner der ursprünglichen C-Codes oder Codierer sie benutzt hätte.


354
2017-10-19 21:09



Es ist ein C Trigraph. ??! ist |, damit ??!??! ist der Betreiber ||


140
2017-10-19 16:58



Wie zuvor schon gesagt ??!??! ist im Wesentlichen zwei Trigraphen (??! und ??! wieder zusammenmustern, die ersetzt werden ||, d Logisches ODER, durch den Präprozessor.

Das folgende Bild, das alle Trigraphen enthält, sollte helfen, alternative Trigraph-Kombinationen zu unterscheiden:

enter image description here (Bild aus C: Ein Referenzhandbuch 5. Ausgabe)

Also ein Trigraph, der aussieht ??(??) wird schließlich zuordnen [], ??(??)??(??) wird ersetzt durch [][] und so weiter, du hast die Idee.

Da Trigraphen während der Vorverarbeitung ersetzt werden, könnten Sie verwenden cpp um einen Blick auf die Ausgabe zu bekommen, mit einem albernen trigr.c Programm:

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

und verarbeitet es mit:

cpp -trigraphs trigr.c 

Sie erhalten eine Konsolenausgabe von

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

Wie Sie bemerken, die Option -trigraphs muss angegeben werden oder sonst cpp wird eine Warnung ausgeben; Dies zeigt an, wie Trigraphen gehören der Vergangenheit an und haben keinen modernen Wert mehr als verwirrende Menschen, die auf sie stoßen könnten.


Was die Gründe für die Einführung von Trigraphen betrifft, ist es besser, wenn man sich die Geschichte Abschnitt von ISO/IEC 646:

ISO / IEC 646 und sein Vorgänger ASCII (ANSI X3.4) bestätigten weitgehend die bestehende Praxis in Bezug auf Zeichenkodierungen in der Telekommunikationsindustrie.

Da ASCII keine Anzahl von Zeichen für andere Sprachen als Englisch enthielt, eine Anzahl von nationalen Varianten wurde gemacht, die einige weniger gebrauchte Charaktere durch benötigte ersetzen


79
2018-03-25 02:24