Legacy: I Trigraph - STB1019/SkullOfSummer GitHub Wiki
I tripgraph sono delle sequenze di caratteri che in compile time vengono sotituite con dei caratteri assenti in alcune vecchie tastiere. Ai giorni nostri i trigraph sono per lo più inutilizzati ma quando appaiono nel codice generano sempre perplessità e (a volte) errori.
I trigraph sono sequenze di caratteri che vengono intepretate e sotituiti da altri caratteri. Tutti i trigraph iniziano con ?? più un carattere di uso comune. Detto con le parole dello standard C99, i trigraph sono:
The trigraph sequences enable the input of characters that are not defined in the Invariant Code Set as described in ISO/IEC 646, which is a subset of the seven-bit US ASCII code set.
Lo standard C99 definisce esattamente questi trigraph:
Trigraph | Viene sostituito con |
---|---|
??= | # |
??( | [ |
??/ | \ |
??) | ] |
??' | ˆ |
??< | { |
??! | | |
??> | } |
??- | ˜ |
Quindi per esempio, in C, scrivere [
o ??(
è la stessa cosa.
gcc 5.4 ignora di default i trigraphs. Se però state usando codice obsoleto e non potete ignorarle (dovete quindi compilare con il flag -trigraphs
), leggete le curiosità!
I trigraph generano, solitamente, perplessità, come nel seguente esempio:
!ErrorHasOccured() ??!??! HandleError();
Che in realtà significa semplicemente (??!
vuol dire |
):
!ErrorHasOccured() || HandleError();
Alla peggio, i trigraph possono introdurre profondi errori, come nel seguente emblematico caso (vedi codice sorgente ):
#include <stdio.h>
int main() {
int x = 1;
for( int i = 0; i < 100; ++i );
// What will the next line do? Increment???????????/
++x;
printf("%d\n", x);
}
Compilando con gcc trigraph.c -o trigraph
(quindi normalmente ignorando i trigraph) otterrete l'output aspettato, ossia 2. Compilando invece con gcc trigraph.c -trigraphs -o trigraph
otterrete una cosa inaspettata, ossia 1. Come mai?
Siccome ??/
vè un trigraph viene tradotto in \
. In C, inserire \
alla fine della riga e poi fare un "a capo" equivale a fare in modo che la riga successiva sia in realtà la continuazione della riga precedente (abbiamo sfruttato questa caratteristica in macrio programming per creare macro lunghe più di una riga). Questo fatto però ci si ritorce conto perché qui facciamo in modo che ++x
sia sulla stessa riga del commento e che quindi venga fagocitato all'interno del commento stesso. Indi l'output 1.
- ISO /IEC 9899:1999, sezione 5.2.1.1 "Trigraph sequences";
- I trigraph generano perplessità
- I trigraph generano errori