Domanda

Secondo C ++ '03 Standard 2.3 / 1:

  

Prima che avvenga qualsiasi altra elaborazione, ogni occorrenza di una delle seguenti sequenze di tre caratteri (& # 8220; sequenze di trigrafia & # 8221;) viene sostituita dal singolo carattere indicato nella Tabella 1.

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

Nella vita reale ciò significa che il codice printf (" What ??! \ n "); comporterà la stampa di What | perché ??! è una sequenza trigraph che viene sostituita dal carattere | .

La mia domanda è quale scopo dell'utilizzo delle trigrafi? C'è qualche vantaggio pratico nell'uso delle trigrafi?

UPD : nelle risposte è stato menzionato che alcune tastiere europee non hanno tutti i caratteri di punteggiatura, quindi i programmatori non statunitensi devono usare le trigrafi nella vita di tutti i giorni?

UPD2 : Visual Studio 2010 ha il supporto trigraph disattivato per impostazione predefinita.

È stato utile?

Soluzione

Questa domanda (sulle digraph strettamente correlate) ha la risposta.

Si riduce al fatto che il set di caratteri ISO 646 non ha tutti i caratteri della sintassi C, quindi ci sono alcuni sistemi con tastiere e display che non possono gestire i caratteri (anche se immagino che questi al giorno d'oggi sono piuttosto rari).

In generale, non è necessario utilizzarli, ma è necessario conoscerli esattamente per il problema riscontrato. Le trigrafi sono la ragione per cui il carattere '? ' ha una sequenza di escape:

'\?'

Quindi un paio di modi in cui puoi evitare il tuo problema di esempio sono:

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

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

Ma devi ricordare quando stai digitando i due '?' personaggi a cui potresti iniziare una trigrafia (e di certo non è mai qualcosa a cui sto pensando).

In pratica, trigraphs e digraphs sono qualcosa di cui non mi preoccupo affatto su una base quotidiana. Ma dovresti esserne consapevole perché una volta ogni due anni ti imbatterai in un bug correlato a loro (e passerai il resto della giornata a maledire la loro esistenza). Sarebbe bello se i compilatori potessero essere configurati per avvisare (o errore) quando si imbatte in una trigrafia o un digraph, quindi potrei sapere che ho qualcosa che dovrei consapevolmente trattare.

E solo per completezza, i digraph sono molto meno pericolosi poiché vengono elaborati come token, quindi un digraph all'interno di una stringa letterale non verrà interpretato come un digraph.

Per una buona educazione sui vari divertimenti con la punteggiatura nei programmi C / C ++ (incluso un bug trigraph che mi farebbe sicuramente togliere i capelli), dai un'occhiata a Articolo GOTW # 86 di Herb Sutter .


Addendum:

Sembra che GCC non elabori (e avvertirà) di trigrafi di default. Alcuni altri compilatori hanno opzioni per disattivare il supporto trigraph (ad esempio IBM). Microsoft ha iniziato a supportare un avviso (C4837) in VS2008 che deve essere esplicitamente abilitato (usando -Wall o qualcosa del genere).

Altri suggerimenti

Da Il linguaggio di programmazione C ++ Special Edition, pagina 829

  

I caratteri speciali ASCII [, ] , {, } , | e \ occupano le posizioni del set di caratteri designate come alfabetiche dall'ISO. Nella maggior parte dei set di caratteri ISO-646 nazionali europei, queste posizioni sono occupate da lettere non presenti nell'alfabeto inglese.

     

Viene fornito un set di trigrafi per consentire ai caratteri nazionali di essere espressi in modo portatile usando un set di caratteri minimo veramente standard. Questo può essere utile per lo scambio di programmi, ma non facilita la lettura dei programmi da parte delle persone. Naturalmente, la soluzione a lungo termine a questo problema è che i programmatori C ++ ottengano apparecchiature che supportino bene sia la loro lingua madre che C ++. Sfortunatamente, questo sembra essere impossibile per alcuni, e l'introduzione di nuove attrezzature può essere un processo frustrantemente lento.

Bambini oggi! : -)

Sì, apparecchiature esterne, come un terminale IBM 3270. Il 3270 non ha, se ricordo, nessuna parentesi graffa! Se volevi scrivere C su un mini / mainframe IBM, dovevi usare le truffe miserabili per ogni limite di blocco. Fortunatamente, dovevo solo scrivere software in C per emulare alcune funzionalità di minicomputer IBM, non in realtà scrivere software C su sul Sistema / 36.

Guarda accanto a " P " chiave:

 tastiera

Hmmm. Difficile da dire. C'è un pulsante extra accanto a "ritorno a capo", e potrei averlo al contrario: forse era il "quot" [" / "] " coppia che mancava. Ad ogni modo, questa tastiera ti causerebbe dolore se dovessi scrivere C.

Inoltre, questi terminali visualizzano EBCDIC, IBM "nativo" set di caratteri mainframe, non ASCII (grazie, Pavel Minaev, per il promemoria).

D'altra parte, come dice la guida GNU C: " Non hai bisogno di questo danno cerebrale. " Il compilatore gcc lascia questa "caratteristica" disabilitato per impostazione predefinita.

Sono da utilizzare su sistemi che mancano di alcuni caratteri nel set di caratteri di base di C ++. Inutile dire che tali sistemi sono estremamente rari.

Le trigrafi sono state proposte per la rimozione in C ++ 0x. Detto questo, sembra esserci ancora una forte argomentazione a sostegno di questi - vedi il documento del comitato C ++ N2910 che ne discute. Apparentemente, EBCDIC è una delle roccaforti principali dove sono necessarie.

Ho visto trigrafi utilizzati nei primi anni '90 per aiutare a convertire i programmi PL / 1 da un mainframe da eseguire / compilare / eseguire il debug su un PC.

Si stavano dilettando con la modifica di PL / I sul PC usando un compilatore da PL / I a C e volevano che il codice funzionasse quando si tornava al mainframe che non supportava parentesi graffe. Ho suggerito che potrebbero usare macro come

#def BEGIN {    
#def END }  

o come alternativa PL / I più amichevole

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

e se volessero davvero essere fantasiosi, potrebbero provare

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

e quindi il programma sembrerebbe come se fosse stato scritto in Pascal. Mi hanno solo guardato in modo strano e non mi hanno parlato per il resto della giornata. Non credo di incolparli. :)

Ciò che ha ucciso lo sforzo e non i tri-grafici, sono state le differenze del sistema IO tra le piattaforme. L'apertura dei file sul PC era molto diversa dal mainframe che avrebbe introdotto troppi kludges per mantenere lo stesso codice in esecuzione su entrambi.

Alcune tastiere europee non hanno (non avevano?) tutti i caratteri di punteggiatura che avevano le tastiere statunitensi, perché avevano bisogno dei tasti per i loro insoliti caratteri alfabetici. Quindi, per esempio (inventando), la tastiera svedese avrebbe un anello A dove si trovava la parentesi graffa.

Per soddisfare quegli utenti, le trigrafi sono un modo per inserire la punteggiatura usando solo i caratteri ASCII più comuni.

Principalmente perché lo standard C li ha introdotti nel 1989, quando c'erano problemi con la presenza dei personaggi che i trigrafi mappano su alcune macchine. Quando lo standard C ++ fu pubblicato nel 1998, la necessità di trigrafi non era grande. Sono una verruca su C; sono altrettanto una verruca su C ++. Era necessario per loro, soprattutto al di fuori del mondo di lingua inglese, ed è per questo che sono stati aggiunti a C.

Sono lì principalmente per motivi storici. Al giorno d'oggi, le tastiere più moderne per la maggior parte delle lingue consentono l'accesso a tutti quei caratteri, ma questo era un problema una volta con alcune tastiere europee. Ecco perché sono state inventate le trigrafi.

Se non sai a cosa servono, non dovresti usarli.

È comunque bene esserne consapevoli, dal momento che potresti usarne uno accidentalmente e involontariamente nel tuo codice.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top