it-swarm.com.de

Was bedeutet das C ??! ??! Betreiber tun?

Ich sah eine Linie von C, die so aussah:

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

Es wurde korrekt kompiliert und scheint in Ordnung zu sein. Es sieht so aus, als würde geprüft, ob ein Fehler aufgetreten ist, und wenn ja, wird dieser behoben. Aber ich bin mir nicht sicher, was es tatsächlich tut oder wie es es tut. Es sieht so aus, als würde der Programmierer versuchen, seine Gefühle zu Fehlern auszudrücken.

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

1865
Peter Olson

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

!ErrorHasOccured() || HandleError();

was aufgrund eines Kurzschlusses äquivalent ist zu:

if (ErrorHasOccured())
    HandleError();

Guru der Woche (beschäftigt sich mit C++, ist aber hier relevant), wo ich das aufgegriffen habe.

Möglicher Ursprung von Trigraphen oder wie @DwB in den Kommentaren hervorhebt, ist es wahrscheinlicher, dass EBCDIC (wieder) schwierig ist. This Die Diskussion im IBM Developerworks 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 nicht im Invariant Code Set definiert sind, wie in ISO/IEC 646 beschrieben, einer Teilmenge des Sieben-Bit-Codesatzes US ASCII.

1508
user786653

Nun, warum das überhaupt existiert, ist wahrscheinlich anders als in Ihrem Beispiel.

Begonnen hat alles vor einem halben Jahrhundert mit der Umnutzung von Hardcopy-Kommunikationsterminals als Computer-Benutzerschnittstellen. In der anfänglichen Unix- und C-Ära war dies der ASR-33-Teletyp.

Dieses Gerät war langsam (10 cps) und laut und hässlich, und seine Ansicht des Zeichensatzes ASCII endete mit 0x5f. Daher hatte es (siehe Abbildung) keinen der folgenden Schlüssel:

{ | } ~ 

Die Trigraphen wurden definiert, um ein bestimmtes Problem zu beheben. Die Idee war, dass C-Programme die ASCII -Untergruppe verwenden könnten, die auf dem ASR-33 zu finden ist, und in anderen Umgebungen die hohen ASCII -Werte fehlen.

Ihr Beispiel besteht eigentlich aus zwei von ??!, die jeweils | bedeuten. Das Ergebnis ist also ||.

Die Leute, die fast per Definition C-Code schrieben, verfügten jedoch über eine moderne Ausrüstung.1 Meine Vermutung lautet also: Jemand, der sich vorführt oder amüsiert und eine Art Osterei im Code zurücklässt, damit Sie es finden.

Es hat sicher funktioniert, es hat zu einer äußerst beliebten SO Frage geführt.

ASR-33 Teletype

ASR-33 Teletype


1. Im Übrigen wurden die Trigraphen vom ANSI-Komitee erfunden, das zum ersten Mal traf, nachdem C zu einem außer Kontrolle geraten war, sodass keiner der ursprünglichen C-Codes oder Codierer sie verwendet hätte .
426
DigitalRoss

Es ist ein C Trigraph . ??! ist |, also ??!??! ist der Operator ||

156
Joel Falcou

Wie bereits erwähnt, ist _??!??!_ im Wesentlichen zwei - Trigraphen (_??!_ und _??!_) Mushed zusammen, die ersetzt werden in _||_, dh das logische ODER , vom Präprozessor.

Die folgende Tabelle, die alle Trigraphen enthält, soll helfen, alternative Trigraphenkombinationen zu unterscheiden:

_Trigraph   Replaces

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

Quelle: C: Ein Referenzhandbuch 5. Auflage

So wird eine Trigraphie, die aussieht wie ??(??), irgendwann _[]_ zugeordnet, ??(??)??(??) wird durch _[][]_ ersetzt, und so weiter.

Da Trigraphen während der Vorverarbeitung ersetzt werden, können Sie cpp verwenden, um mithilfe eines albernen _trigr.c_ -Programms selbst eine Ansicht der Ausgabe zu erhalten:

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

und verarbeite es mit:

_cpp -trigraphs trigr.c 
_

Sie erhalten eine Konsolenausgabe von

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

Wie Sie feststellen können, muss die Option _-trigraphs_ angegeben werden, andernfalls gibt cpp eine Warnung aus. Dies zeigt, wie Trigraphen der Vergangenheit angehören und keinen anderen modernen Wert haben, als Menschen zu verwirren, die auf sie stoßen könnten .


Was die Gründe für die Einführung von Trigraphen angeht, ist dies besser verständlich, wenn man sich den Abschnitt zur Geschichte von ISO/IEC 646 ansieht:

ISO/IEC 646 und sein Vorgänger ASCII (ANSI X3.4) haben die bestehende Praxis in Bezug auf Zeichenkodierungen in der Telekommunikationsbranche weitgehend unterstützt.

Da ASCII nicht die für andere Sprachen als Englisch erforderliche Anzahl von Zeichen enthielt, wurden mehrere nationale Varianten erstellt, die einige weniger wichtige ersetzen. benutzte Zeichen mit benötigten .

(Hervorhebung von mir)

Im Wesentlichen wurden einige benötigte Zeichen (für die ein Trigraph existiert) in bestimmten nationalen Varianten ersetzt. Dies führt zur alternativen Darstellung mit Trigraphen, die aus Zeichen bestehen, die andere Varianten noch hatten.

133