J'ai vu une ligne de C qui ressemblait à ceci:
!ErrorHasOccured() ??!??! HandleError();
Il a compilé correctement et semble fonctionner correctement. Il semble qu'il vérifie si une erreur s'est produite et si c'est le cas, il la gère. Mais je ne suis pas vraiment sûr de ce qu'il fait réellement ou comment il le fait. Il semble que le programmeur essaie d'exprimer ses sentiments sur les erreurs.
Je n'ai jamais vu le ??!??!
précédent dans aucun langage de programmation, et je ne trouve aucune documentation pour cela nulle part. (Google n'aide pas avec les termes de recherche comme ??!??!
). Que fait-il et comment fonctionne l'exemple de code?
!ErrorHasOccurred() ??!???! HandleError();
compiler? Voilà??!
???
!
. Prouve le point?ErrorHasOccured() && HandleError()
me préfère plutôt . C'est aussi comme ça que Lua le fait.Réponses:
??!
est un trigraphe qui se traduit par|
. Donc ça dit:qui, en raison des courts-circuits, équivaut à:
Gourou de la semaine (traite du C ++ mais pertinent ici), où j'ai repris cela.
Origine possible des trigraphes ou comme le souligne @DwB dans les commentaires, il est plus probable en raison de la difficulté (encore une fois) d'EBCDIC. Cette discussion sur la carte IBM developerworks semble soutenir cette théorie.
D'après ISO / IEC 9899: 1999 §5.2.1.1, note de bas de page 12 (h / t @ Random832):
la source
if (ErrorHasOccured()) HandleError()
. Heureusement, vous ne rencontrez généralement cet idiome qu'en code perl.ErrorHasOccurred() && HandleError();
-dire, si vous êtes habitué au shell scripting. :)Eh bien, pourquoi cela existe en général est probablement différent de la raison pour laquelle il existe dans votre exemple.
Tout a commencé il y a un demi-siècle avec la réorientation des terminaux de communication sur papier en tant qu'interfaces utilisateurs informatiques. Dans l'ère Unix et C initiale qui était le télétype ASR-33.
Cet appareil était lent (10 cps) et bruyant et laid et sa vue du jeu de caractères ASCII se terminait à 0x5f, donc il n'avait (regardez attentivement la photo) aucune des clés:
Les trigraphes ont été définis pour résoudre un problème spécifique. L'idée était que les programmes C pouvaient utiliser le sous-ensemble ASCII trouvé sur l'ASR-33 et dans d'autres environnements sans les valeurs ASCII élevées.
Cependant, les gens qui écrivent le code C presque par définition avaient un équipement moderne, 1 donc je suppose: quelqu'un montrer amusant themself ou, en laissant une sorte d'oeuf de Pâques dans le code pour vous de trouver.
Cela a bien sûr fonctionné, cela a conduit à une question SO très populaire.
Télétype ASR-33
1. D'ailleurs, les trigraphes ont été inventés par le comité ANSI, qui s'est réuni pour la première fois après que C est devenu un succès fulgurant, donc aucun des codes ou codeurs C d'origine ne les aurait utilisés.
la source
#
été remplacé par£
. Dans d'autres régions, peut-être que "ASCII" n'avait pas d'appareilif (x || y) { a[i] = '\0'; }
ressemblerif (x öö y) ä aÄiÅ = 'Ö0'; å
au mauvais jeu de caractères.Il est un C trigraphes .
??!
est|
, est donc??!??!
l'opérateur||
la source
<iso646.h>
fichier d'en-tête.Comme déjà indiqué, il
??!??!
y a essentiellement deux trigraphes (??!
et??!
encore une fois) assemblés qui sont remplacés-traduits en||
, c'est -à -dire le OU logique , par le préprocesseur.Le tableau suivant contenant chaque trigraphe devrait aider à lever l'ambiguïté des combinaisons de trigraphes alternatives:
Source: C: A Reference Manual 5th Edition
Donc, un trigraphe qui ressemble
??(??)
finira par correspondre[]
,??(??)??(??)
sera remplacé par[][]
et ainsi de suite, vous avez l'idée.Étant donné que les trigraphes sont substitués pendant le prétraitement, vous pouvez utiliser
cpp
pour obtenir vous-même une vue de la sortie, à l'aide d'untrigr.c
programme stupide :et le traiter avec:
Vous obtiendrez une sortie console de
Comme vous pouvez le constater, l'option
-trigraphs
doit être spécifiée, sinoncpp
un avertissement sera émis; cela indique comment les trigraphes sont une chose du passé et sans valeur moderne autre que de confondre les gens qui pourraient les croiser .Quant à la justification de l'introduction des trigraphes, elle est mieux comprise lorsque l'on examine la section historique de l'ISO / CEI 646 :
(c'est moi qui souligne)
Ainsi, en substance, certains caractères nécessaires (ceux pour lesquels il existe un trigraphe) ont été remplacés dans certaines variantes nationales. Cela conduit à la représentation alternative utilisant des trigraphes composés de caractères que d'autres variantes avaient encore autour.
la source