Question

J'ai vu une ligne de C qui ressemblait à ceci:

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

Il a été compilé correctement et semble fonctionner ok. Il semble que c'est de vérifier si une erreur est survenue, et si elle a, il le gère. Mais je ne suis pas vraiment sûr de ce qu'il est en train de faire ou comment il le fait. Il ne ressemble au programmeur tente d'exprimer leurs sentiments au sujet des erreurs.

Je n'ai jamais vu ??!??! auparavant dans un langage de programmation, et je ne peux pas trouver de la documentation pour nulle part. (Google ne permet pas de termes de recherche comme ??!??!). Que fait-il et comment l'exemple de code de travail?

Était-ce utile?

La solution

??! est un trigraphes qui se traduit |. Ainsi, il dit:

!ErrorHasOccured() || HandleError();

qui, en raison d'un court-circuit, est équivalente à:

if (ErrorHasOccured())
    HandleError();

Guru (les traite C ++, mais pertinent ici) de la semaine, où je pris cela.

Origine possible de trigraphes ou @DwB indique dans les commentaires, il est plus probable en raison de EBCDIC être difficile (encore une fois). Cette discussion sur IBM developerWorks conseil semble soutenir cette théorie.

De la norme ISO / IEC 9899: 1999 §5.2.1.1, note 12 (h / t @ Random832):

Les séquences d'trigraph permettre l'entrée de caractères qui ne sont pas définies dans le Code Set Invariant que décrit dans la norme ISO / CEI 646, qui est un sous-ensemble du code ASCII US sept bits jeu.

Autres conseils

Eh bien, pourquoi cela existe en général est probablement différente de celle pour laquelle il existe dans votre exemple.

Tout a commencé il y a un demi-siècle avec repurposing terminaux de communication comme interfaces copie papier utilisateur de l'ordinateur. Dans Unix initiale et ère C qui a été l'ASR-33 téléscripteur.

Cet appareil a été lent (10 cps) et bruyant et laid et son point de vue de l'ensemble de caractères ASCII terminée à 0x5F, il avait (regarder attentivement la photo) aucune des touches:

{ | } ~ 

Le trigraphes ont été définis pour résoudre un problème spécifique. L'idée était que les programmes C pourraient utiliser le sous-ensemble ASCII trouvés sur l'ASR-33 et dans d'autres environnements les valeurs manquantes haute ASCII.

Votre exemple est en fait deux ??!, chaque sens |, de sorte que le résultat est ||.

Cependant, les gens qui écrivent le code C presque par définition ont des équipements modernes, 1 donc je suppose: une personne exhibant ou themself amusant, en laissant une sorte d'oeuf de Pâques dans le code pour vous trouver.

Il vous a travaillé, il a conduit à une question SO très populaire.

 ASR-33 Teletype

ASR-33 Teletype


1. Pour cette question, les trigrammes ont été inventés par le comité ANSI, qui a d'abord rencontré après C devenir un succès fulgurant, de sorte qu'aucun du code d'origine C ou codeurs aurait pu les utiliser.

C'est un C trigraphes . ??! est |, de sorte ??!??! est le || opérateur

Comme indiqué ??!??! est essentiellement deux trigraphes ( ??! et ??! à nouveau) mushed ensemble que get-a remplacé traduit à ||, à savoir le OU logique , par le préprocesseur.

Le tableau suivant contient tous les trigraphes devrait aider les combinaisons de désambiguïser trigraph autre:

Trigraph   Replaces

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

Source: C: Manuel de référence 5ème édition

Ainsi, un trigraphes qui ressemble ??(??) finiront par carte à [], ??(??)??(??) sera remplacé par se [][] et ainsi de suite, vous avez l'idée.

Depuis trigraphes sont substitués pendant que vous pouvez utiliser cpp pour obtenir une vue de la sortie vous-même, en utilisant un programme trigr.c stupide:

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

avec et traitement:

cpp -trigraphs trigr.c 

Vous obtiendrez une sortie de la console de

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

Comme vous pouvez le remarquer, l'-trigraphs option doit être spécifiée ou bien cpp émettra un avertissement; cela indique comment trigraphes sont une chose du passé et sans valeur autre que moderne embrouiller les gens qui pourraient tomber sur les .


En ce qui concerne la raison d'être de l'introduction trigraphes, il est mieux comprise quand on regarde la section d'histoire de l'ISO / CEI 646 :

ISO / CEI 646 et son prédécesseur ASCII (ANSI X3.4) largement approuvé les pratiques existantes en ce qui concerne les codages de caractères dans l'industrie des télécommunications.

ASCII n'a pas fourni un certain nombre de caractères nécessaires pour les langues autres que l'anglais, un certain nombre de variantes nationales ont été faites qui ont remplacé certains caractères moins utilisés avec ceux nécessaires .

(Souligné par l'auteur)

Donc, en substance, certains caractères nécessaires (ceux pour lesquels un trigraphes existe) ont été remplacés dans certaines variantes nationales. Cela conduit à la représentation alternative à l'aide de caractères trigraphes composés que d'autres variantes avaient encore autour.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top