web-dev-qa-db-fra.com

Objectif des séquences Trigraph en C ++?

Selon C++ '03 Standard 2.3/1:

Avant tout autre traitement, chaque occurrence d'une des séquences de trois caractères suivantes ("séquences trigraphiques") est remplacée par le caractère unique indiqué dans le tableau 1.

----------------------------------------------------------------------------
| trigraph | replacement | trigraph | replacement | trigraph | replacement |
----------------------------------------------------------------------------
| ??=      | #           | ??(      | [           | ??<      | {           |
| ??/      | \           | ??)      | ]           | ??>      | }           |
| ??’      | ˆ           | ??!      | |           | ??-      | ˜           |
----------------------------------------------------------------------------

Dans la vraie vie, cela signifie que le code printf( "What??!\n" ); entraînera l'impression de What| Car ??! Est une séquence de trigraphe qui est remplacée par le caractère |.

Ma question est à quoi sert l'utilisation des trigraphes? Y a-t-il un avantage pratique à utiliser les trigraphes?

UPD : Dans les réponses, il a été mentionné que certains claviers européens n'ont pas tous les caractères de ponctuation, donc les programmeurs non américains doivent utiliser des trigraphes dans la vie quotidienne?

PD2: Visual Studio 2010 a la prise en charge du trigraphe désactivée par défaut.

118

Cette question (sur les digraphes étroitement liés) a la réponse.

Cela se résume au fait que le jeu de caractères ISO 646 n'a pas tous les caractères de la syntaxe C, il existe donc certains systèmes avec des claviers et des écrans qui ne peuvent pas traiter les caractères (bien que j'imagine que ceux-ci sont assez rares aujourd'hui).

En général, vous n'avez pas besoin de les utiliser, mais vous devez les connaître pour exactement le problème que vous avez rencontré. Les trigraphes sont la raison pour laquelle le '? 'a une séquence d'échappement:

'\?'

Donc, deux façons d'éviter votre problème d'exemple sont les suivantes:

 printf( "What?\?!\n" ); 

 printf( "What?" "?!\n" ); 

Mais vous devez vous rappeler quand vous tapez les deux '?' les personnages que vous pourriez démarrer un trigraphe (et ce n'est certainement jamais quelque chose à quoi je pense).

Dans la pratique, les trigraphes et les digraphes sont quelque chose dont je ne m'inquiète pas du tout au quotidien. Mais vous devez en être conscient car une fois tous les deux ans, vous rencontrerez un bug qui leur est lié (et vous passerez le reste de la journée à maudire leur existence). Ce serait bien si les compilateurs pouvaient être configurés pour avertir (ou faire une erreur) quand il rencontre un trigraphe ou un digraphe, donc je pourrais savoir que j'ai quelque chose que je devrais traiter en connaissance de cause.

Et juste pour être complet, les digraphes sont beaucoup moins dangereux car ils sont traités comme des jetons, donc un digraphe à l'intérieur d'un littéral de chaîne ne sera pas interprété comme un digraphe.

Pour une bonne éducation sur divers divertissements avec la ponctuation dans les programmes C/C++ (y compris un bug de trigraphe qui me ferait définitivement arracher mes cheveux), jetez un œil à article GOTW # 86 de Herb Sutter .


Addenda:

Il semble que GCC ne traite pas (et avertit) des trigraphes par défaut. Certains autres compilateurs ont des options pour désactiver la prise en charge du trigraphe (IBM par exemple). Microsoft a commencé à prendre en charge un avertissement (C4837) dans VS2008 qui doit être explicitement activé (en utilisant -Wall ou quelque chose).

89
Michael Burr

De The C++ Programming Language Édition spéciale, page 829

Le ASCII caractères spéciaux [, ], {, }, |, et \ occupe les positions du jeu de caractères désignées comme alphabétiques par l'ISO. Dans la plupart des jeux de caractères nationaux européens ISO-646, ces positions sont occupées par des lettres introuvables dans l'alphabet anglais.

Un ensemble de trigraphes est fourni pour permettre aux caractères nationaux d'être exprimés de manière portable en utilisant un jeu de caractères minimal vraiment standard. Cela peut être utile pour l'échange de programmes, mais cela ne facilite pas la lecture des programmes. Naturellement, la solution à long terme à ce problème consiste pour les programmeurs C++ à obtenir un équipement qui prend en charge à la fois leur langue maternelle et C++. Malheureusement, cela semble irréalisable pour certains, et l'introduction de nouveaux équipements peut être un processus frustrant et lent.

20
Rob

Les enfants aujourd'hui! :-)

Oui, des équipements étrangers, comme un terminal IBM 3270. Si je me souviens bien, le 3270 n'a pas d'appareil dentaire frisé! Si vous vouliez écrire C sur un mini/mainframe IBM, vous deviez utiliser les trigraphes misérables pour chaque limite de bloc. Heureusement, je n'ai eu qu'à écrire des logiciels en C pour émuler certaines installations de mini-ordinateurs IBM, pas vraiment écrire des logiciels C sur le système/36.

Regardez à côté de la touche "P":

keyboard

Hmmm. Dur à dire. Il y a un bouton supplémentaire à côté de "retour chariot", et je pourrais l'avoir à l'envers: c'était peut-être la paire "["/"]" qui manquait. En tout cas, ce clavier vous causerait du chagrin si vous deviez écrire C.

De plus, ces terminaux affichent EBCDIC, le jeu de caractères mainframe "natif" d'IBM, pas ASCII (merci Pavel Minaev pour le rappel).

D'un autre côté, comme le guide GNU C dit: "Vous n'avez pas besoin de ces dommages cérébraux." Le compilateur gcc laisse cette "fonctionnalité" désactivée par défaut.

19
Roboprog

Ils sont destinés à être utilisés sur des systèmes dépourvus de certains caractères du jeu de caractères de base de C++. Il va sans dire que de tels systèmes sont extrêmement rares.

13
CB Bailey

Il a été proposé de supprimer les trigraphes en C++ 0x. Cela dit, il semble toujours y avoir des arguments solides à leur soutien - voir le document du comité C++ N291 qui en discute. Apparemment, EBCDIC est un bastion majeur où ils sont nécessaires.

8
Pavel Minaev

J'ai vu des trigraphes utilisés au début des années 90 pour aider à convertir les programmes PL/1 d'un ordinateur central à exécuter/compiler/déboguer sur un PC.

Ils essayaient de modifier PL/I sur le PC à l'aide d'un compilateur PL/I to C et ils voulaient que le code fonctionne lorsqu'il est ramené au mainframe qui ne supportait pas les accolades. J'ai suggéré qu'ils pourraient utiliser des macros comme

#def BEGIN {    
#def END }  

ou comme alternative PL/I plus conviviale

#def BEGIN ??<
#def END ??>

et s'ils voulaient vraiment devenir fantaisistes, ils pourraient essayer

#ifdef MAINFRAME
    #def BEGIN ??<
    #def END ??>
#else
    #def BEGIN {    
    #def END }  
#endif

puis le programme ressemblerait à ce qu'il a été écrit en Pascal. Ils m'ont juste regardé drôle et ne me parlaient pas pour le reste de la journée. Je ne pense pas que je les blâme. :)

Ce qui a tué l'effort, pas les tri-graphes, ce sont les différences de système IO entre les plates-formes. L'ouverture des fichiers sur le PC était tellement différente de l'unité centrale qu'elle aurait introduit beaucoup trop de contraintes pour garder le même code en cours d'exécution sur les deux.

4
Kelly S. French

Certains claviers européens n'ont pas (non?) Tous les caractères de ponctuation que possédaient les claviers américains, car ils avaient besoin des clés pour leurs caractères alphabétiques inhabituels. Ainsi, par exemple (pour inventer cela), le clavier suédois aurait un anneau en A où se trouvait l'accolade frisée.

Pour accueillir ces utilisateurs, les trigraphes sont un moyen d'entrer la ponctuation en utilisant uniquement les caractères ASCII les plus courants.

3
Ned Batchelder

Ils sont là principalement pour des raisons historiques. De nos jours, la plupart des claviers modernes pour la plupart des langues permettent d'accéder à tous ces caractères, mais cela était un problème avec certains claviers européens. C'est pourquoi les trigraphes ont été inventés.

Si vous ne savez pas à quoi ils servent, vous ne devriez pas les utiliser.

Il est toujours bon d'en être conscient, car vous pouvez en utiliser accidentellement et involontairement un dans votre code.

2
sbi

Principalement parce que la norme C les a introduits en 1989, quand il y avait des problèmes avec la présence des caractères auxquels les trigraphes mappent sur certaines machines. Au moment de la publication de la norme C++ en 1998, le besoin de trigraphes n'était pas grand. Ils sont une verrue sur C; ils sont tout autant une verrue en C++. Il y en avait un besoin - surtout en dehors du monde anglophone - c'est pourquoi ils ont été ajoutés à C.

2
Jonathan Leffler