Scopo delle sequenze di Trigraph in C ++?


127

Secondo C ++ '03 Standard 2.3 / 1:

Prima che avvenga qualsiasi altra elaborazione, ciascuna occorrenza di una delle seguenti sequenze di tre caratteri ("sequenze di trigrafia") è 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 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.


Alcune punteggiatura sono più difficili da raggiungere sulle tastiere europee (al punto che alcuni programmatori usano il layout americano per digitare più velocemente) Non ne hai mai visto uno in cui le punteggiatura mancano del tutto - forse per le lingue slave?
Peter

2
Può accadere che alcuni terminali e / o la virtualizzazione non ti permettano di accedere facilmente ad alcuni personaggi. Nella mia esperienza, l'autore principale è la tilde.
Francesco,

1
digitando questo sulla mia tastiera DE-deadkeys, # è un tasto accanto a return, \ è "AltGr" + "ß" (vicino a 0), ^ è "^" + "^" (a causa di deadkey; accanto a 1) , [è "AltGr" + "8",] è "AltGr" + "9", | è "AltGr" + "<", {è "AltGr" + "7",} è "AltGr" + "0" e ~ è "~" + "~" (a causa di deadkey, appena sopra #). quindi non è un grosso problema. le mie dita sono come scrivere queste combinazioni da sole :-D
nonchip

1
Ho pensato che fosse normale avere due layout di tastiera e cambiarli in base al lavoro che sto facendo sul computer. È il modo comune nella regione dell'Europa centrale. È abbastanza inquietante usare queste trigrafi. Vorrei votare per la rimozione di questo standard.
VX

Risposte:


97

Questa domanda (sui digrafi strettamente correlati) 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 riescono a gestire i caratteri (anche se immagino che siano piuttosto rari al giorno d'oggi).

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, trigrafi e digrafi 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 di avere qualcosa con cui dovrei consapevolmente occuparmi.

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

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


Addendum:

Sembra che GCC non elabori (e avvertirà) le trigrafi per impostazione predefinita. 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).


La compatibilità con C è l'unica ragione? È possibile incontrarli nei moderni programmi C ++?
Kirill V. Lyadvinsky il

Sì, anche il C ++ supporta trigrafi e digrafi.
Michael Burr,

4
Come ricordo, almeno un compilatore che ho usato (g ++?) Richiede un'opzione esplicita da riga di comando prima che trigraph eo digraph vengano tradotti, altrimenti viene dato un avvertimento ma nessuna sostituzione.
KTC,

1
@ Jla3ep - Personalmente non ho mai avuto bisogno di trigrafi, ma sfortunatamente i compilatori elaboreranno il codice con loro, quindi è necessario esserne consapevoli (per evitare un uso accidentale). Inoltre, se ottieni codice da qualche altra parte, potresti imbatterti nel loro uso intenzionale, ma sarebbe estremamente insolito. Penso di essermi imbattuto in trigrafi intenzionalmente usati una volta in 20+ anni (era un po 'di codice per un mainframe IBM).
Michael Burr,

1
Mi dà davvero sui nervi solo quando i trigrafi vengono espansi nei commenti per fare cose sorprendenti.
Giosuè

23

I bambini oggi! :-)

Sì, apparecchiature straniere, come un terminale IBM 3270. Il 3270 non ha, se ricordo, nessuna parentesi graffa! Se si voleva scrivere C su un IBM mini / mainframe, si doveva utilizzare i trigrammi miserabili per ogni confine di blocco. Fortunatamente, dovevo solo scrivere software in C per emulare alcune strutture di minicomputer IBM, non in realtà scrivere software C su System / 36.

Guarda accanto al tasto "P":

tastiera

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

Inoltre, questi terminali visualizzano EBCDIC, il set di caratteri mainframe "nativo" di IBM, 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" disabilitata per impostazione predefinita.


1
C'è un pulsante di reset sulla tastiera. È fantastico! Strano che per prima cosa ha attirato la mia attenzione.
1346 a 16:54

10
Chiunque desideri utilizzare C ++ 17 su una macchina EBCDIC, dovrebbe essere incarcerato per necrofilia.
SF.

A meno che una piattaforma non ha caratteri affatto diversi da quelli in iso646, potrebbe non tutto ciò che può essere fatto con trigrammi, essere fatto richiedendo che ogni implementazione definisce né un backslash oppure qualsiasi carattere che non è nel set di caratteri C come carattere "meta", sostituire tutti i riferimenti alla barra rovesciata nello standard con "meta" e l'aggiunta di barre rovesciate / meta per tutti i membri del set di caratteri C che non sono in ISO-646?
supercat

22

Dall'edizione The C++ Programming Languagespeciale, pagina 829

I caratteri ASCII speciali [, ], {, }, |, e\ occupano posizioni di set di caratteri alfabetici indicati come da ISO. Nella maggior parte dei set di caratteri ISO-646 nazionali europei, queste posizioni sono occupate da lettere che non si trovano nell'alfabeto inglese.

Viene fornito un set di trigrafi per consentire ai caratteri nazionali di essere espressi in modo portatile utilizzando 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.


7
"L'introduzione di nuove attrezzature può essere un processo frustrantemente lento". Soprattutto rispetto al processo rapido e indolore di standardizzazione delle funzionalità del linguaggio di programmazione.
Jforberg,

4
Se questo è un kludge per i layout di tastiera, allora è divertente che non ci sia alcuna trigrafia, ad esempio per la digitazione `, che manca all'italiano e molti altri layout di tastiera
badp

15

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.


2
Significa che non li userò mai nella vita reale?
Kirill V. Lyadvinsky il

1
In che paese vivi? Non tutte le tastiere per tutte le lingue hanno i tasti necessari.
David Thornley,

2
Sì, ma potrebbe essere necessario essere consapevoli dell'esistenza nel caso in cui uno causi un risultato imprevisto quando ci si imbatte in, diciamo, in una stringa letterale.
CB Bailey,

4
@David Thornley: la maggior parte dei sistemi moderni supporta tutti i caratteri di base di C ++ anche se non si trovano nella posizione convenzionale o richiedono una sequenza di modifica per digitare. Le trigrafi dovevano essere mantenute solo nel codice sorgente sui sistemi in cui il carattere non può essere effettivamente rappresentato nel set di caratteri di sistema. Continuo a sostenere che tali sistemi sono estremamente rari.
CB Bailey,

9

Trigraphs sono stati proposti 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.


Sì, quella "lingua straniera"! :-)
Roboprog,

In realtà non dicono molto tranne "i risultati di un sondaggio interno sul feedback dei clienti", ma ah bene. Sono sorpreso che EBCDIC sia ancora in uso diffuso (e che questi sistemi
prevedano

5

Ho visto trigrafi usati 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 l'editing di PL / I sul PC usando un compilatore da PL / I a C e volevano che il codice funzionasse quando tornarono 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 kludge per mantenere lo stesso codice in esecuzione su entrambi.


PL / 1 = versione IBM di C (più o meno). Vedi il mio commento: i terminali IBM non hanno chiavi '{' / '}' :-( Un po 'difficile scrivere C [++] su uno di questi, altrimenti.
Roboprog

3

Principalmente perché lo standard C li ha introdotti nel 1989, quando c'erano problemi con la presenza dei personaggi su cui 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 ++. C'era la necessità per loro - specialmente al di fuori del mondo di lingua inglese - motivo per cui sono stati aggiunti a C.


1
Ho sempre sospettato che IBM non parlasse inglese :-)
Roboprog,

3

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 tali utenti, le trigrafi sono un modo per inserire la punteggiatura utilizzando solo i caratteri ASCII più comuni.


4
Le trigraph non riguardano in realtà l'immissione dei dati (rendono il codice piuttosto illeggibile), riguardano piuttosto i sistemi che in realtà non hanno i caratteri richiesti. Se un sistema è in grado di registrare e visualizzare il carattere, anche se è necessario digitare una sequenza di tasti simile a una trigrafia, sarebbe molto più semplice non conservare la sequenza di trigrafi nella sorgente.
CB Bailey,

2

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.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.