opérateur - ou exclusif en c




Qu'est-ce que le C ??! ??! opérateur faire? (3)

C'est un trigraph C. ??! est | , alors ??!??! est l'opérateur ||

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

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

Il 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 le 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 à propos des erreurs.

Je n'ai jamais vu le ??!??! avant dans n'importe quel langage de programmation, et je ne peux pas trouver de documentation pour cela n'importe où. (Google n'aide pas avec des termes de recherche comme ??!??! ). Que fait-il et comment fonctionne l'exemple de code?


Comme déjà dit ??!??! est essentiellement deux trigraphs ( ??! et ??! nouveau) mushed ensemble qui sont remplacés-traduits en || , c'est-à-dire le OU logique , par le préprocesseur.

L'image suivante contenant tous les trigraphes devrait aider à désambiguïser les combinaisons trigraphiques alternatives:

(Image tirée de C: A Reference Manual 5th Edition )

Donc, un trigraphe qui ressemble à ??(??) sera éventuellement mapper à [] , ??(??)??(??) sera remplacé par [][] et ainsi de suite, vous avez l'idée.

Puisque les trigraphes sont substitués pendant le pré-traitement, vous pouvez utiliser cpp pour obtenir une vue de la sortie vous-même, en utilisant un programme idiot trigr.c :

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

et le traiter avec:

cpp -trigraphs trigr.c 

Vous obtiendrez une sortie de console de

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

Comme vous pouvez le constater, l'option -trigraphs doit être spécifiée sinon cpp émet un avertissement; ceci indique comment les trigraphes sont une chose du passé et n'ont aucune valeur moderne autre que confondant les gens qui pourraient les rencontrer .

En ce qui concerne la justification de l'introduction des trigraphes, il est plus facile de comprendre la section Historique de l' ISO/IEC 646 :

L'ISO / CEI 646 et son prédécesseur ASCII (ANSI X3.4) approuvaient largement la pratique existante concernant les codages de caractères dans l'industrie des télécommunications.

Comme ASCII ne fournissait pas un nombre de caractères requis pour les langues autres que l'anglais, un certain nombre de variantes nationales ont été faites qui ont substitué certains caractères moins utilisés aux caractères nécessaires .

(emphase mienne)

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


??! est un trigraph qui se traduit par | . Donc ça dit:

!ErrorHasOccured() || HandleError();

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

if (ErrorHasOccured())
    HandleError();

Guru of the Week (traite avec C ++ mais pertinent ici), où j'ai ramassé ceci.

L'origine possible des trigraphes ou comme le fait remarquer @DwB dans les commentaires est probablement dû au fait que EBCDIC est difficile (encore une fois). This discussion sur le forum IBM developerworks semble soutenir cette théorie.

D'ISO / CEI 9899: 1999 §5.2.1.1, note de bas de page 12 (h / t @ Random832):

Les séquences trigraphiques permettent l'entrée de caractères qui ne sont pas définis dans l'ensemble de codes invariants, comme décrit dans l'ISO / CEI 646, qui est un sous-ensemble de l'ensemble de codes US ASCII à sept bits.





trigraphs