2014-05-23 18 views
5

Mi sono imbattuto in un codice dall'aspetto strano. Non sembra nemmeno C, ma con mia sorpresa si compila e gira sul mio compilatore C. Si tratta di un'estensione non standard al linguaggio C e, in tal caso, qual è la ragione?Qual è il significato di questi strani punti interrogativi?

??=include <stdio.h> 

int main() 
??< 
    const char arr[] = 
    ??< 
    0xF0 ??! 0x0F, 
    ??-0x00, 
    0xAA ??' 0x55 
    ??>; 

    for(int i=0; i<sizeof(arr)/sizeof(*arr); i++) 
    ??< 
    printf("%X??/n", (unsigned char)arr??(i??)); 
    ??> 

    return 0; 
??> 

uscita:

FF 
FF 
FF 
+0

Questo è il mio primo passo verso l'offuscamento. Non penso che molti programmatori di codici C siano a conoscenza di questo. – Abhineet

+2

possibile duplicato di [significato di \ '??? - \' nel codice C++] (http://stackoverflow.com/questions/16662276/meaning-of-in-c-code) – usr2564301

+1

Dovresti rifattorizzare il codice che assomiglia Questo. Un modo rapido sarebbe sostituire "?? =" con "?? =", Eseguire gcc -trigraph -E su di esso e quindi sostituire "?? =" Nell'output con "#" mentre si rimuovono le prime righe di prodotto da gcc. –

risposta

11

Il codice è pienamente aderente allo standard a qualsiasi versione dello standard C. Il meccanismo ?? si chiama trigrammi ed è stato introdotto in C per consentire un modo alternativo di stampare determinati simboli. Sembra che il programma sia stato scritto come una dimostrazione di varie sequenze di trigraph.

Torna nei giorni, molti computer e le loro tastiere erano basati su un vecchio tavolo simbolo chiamato ISO 646 che non conteneva tutti i simboli utilizzati nel linguaggio C, come ad esempio \ { } [ ]. Ciò ha reso impossibile per i programmatori di alcuni paesi persino scrivere C, perché al loro layout di tastiera nazionale mancavano i simboli necessari. Invece di rifare le tastiere e le tabelle dei simboli, il linguaggio C è stato modificato.

Sono stati quindi introdotti i trigrafi. Oggi sono considerati una funzionalità completamente obsoleta e non è consigliabile utilizzarli. Ad esempio, GCC ti avviserà se li usi. Tuttavia, rimangono nello standard C per la retrocompatibilità e tutti i compilatori C devono supportarli.

Le sequenze trigraph esistenti (sequenze C11 5.2.1.1 trigraph):

??= # 
??( [ 
??/ \ 
??) ] 
??'^
??< { 
??! | 
??> } 
??- ~ 

La colonna di sinistra è la sequenza trigraph e la colonna di destra è il suo significato.