2014-05-23 14 views
5

Natknąłem się na jakiś dziwnie wyglądający kod. To nawet nie wygląda jak C, ale ku mojemu zdziwieniu kompiluje i działa na moim kompilatorze C. Czy jest to jakieś niestandardowe rozszerzenie języka C, a jeśli tak, jaki jest tego powód?Jakie jest znaczenie tych dziwnych znaków zapytania?

??=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; 
??> 

wyjściowa:

FF 
FF 
FF 
+0

To jest mój pierwszy krok w kierunku zaciemniania. Nie sądzę, że wielu programistów C jest tego świadomych. – Abhineet

+2

możliwy duplikat [znaczenie \ "??? - \" w kodzie C++] (http://stackoverflow.com/questions/16662276/meaning-of-in-c-code) – usr2564301

+1

Powinieneś refactor code, który wygląda to. Szybkim sposobem byłoby zastąpienie "?? =" przez "?? =", Uruchomienie gcc -trigraph -E na nim, a następnie zamiana "?? =" Na wyjściu za pomocą "#" podczas usuwania pierwszych kilku linii wyjście przez gcc. –

Odpowiedz

11

Kod jest w pełni zgodny z norma każdej wersji standardu C. Mechanizm ?? jest nazywany trigraphs i został wprowadzony do C, aby umożliwić alternatywny sposób drukowania niektórych symboli. Wygląda na to, że program został napisany jako demonstracja różnych sekwencji trigraficznych.

Dawno temu wiele komputerów i ich klawiatur bazowało na starej tabeli symboli o nazwie ISO 646, która nie zawierała wszystkich symboli używanych w języku C, takich jak \ { } [ ]. To uniemożliwiło programistom z niektórych krajów nawet napisanie C, ponieważ ich układ klawiatury narodowej nie zawierał niezbędnych symboli. Zamiast przerobić klawisze i tabele symboli, język C został zmieniony.

Dlatego wprowadzono trigrafię. Dziś są uważane za całkowicie przestarzałą cechę i nie zaleca się ich używania. GCC na przykład da ci ostrzeżenie, jeśli z nich skorzystasz. Mimo to pozostają w standardzie C ze względu na kompatybilność wsteczną i wszystkie kompilatory języka C muszą je obsługiwać.

Istniejące sekwencje trigraph są (sekwencja C11 5.2.1.1 Trigraph)

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

Lewa kolumna sekwencja trigraph a prawa kolumna ma sens.