2013-06-22 10 views
7
int main(void) 
{ 
    #if 0 
    something" 
    #endif 
    return 0; 
} 

Powyższy prosty program generuje ostrzeżenie: missing terminating " character w gcc. Wydaje się to dziwne, ponieważ oznacza to, że kompilator dopuszcza, że ​​bloki kodu między #if 0 i endif mają niepoprawną instrukcję, taką jak something, ale nie zawierają podwójnych cytatów ", które nie są parami. To samo dzieje się przy korzystaniu z #ifdef i #ifndef.Bloki kodu pomiędzy #if 0 i #endif muszą mieć sparowane podwójne cudzysłowy?

Prawdziwe komentarze są w porządku tutaj:

int main(void) 
{ 
    /* 
    something" 
    */ 
    return 0; 
} 

Dlaczego? A pojedynczy cytat: ' zachowuje się podobnie, czy są jakieś inne tokeny, które traktują specjalnie?

+0

Który kompilator? –

+0

@ IgnacioVazquez-Abrams Użyłem online gcc do przetestowania http://www.compileonline.com/compile_c_online.php –

+0

Nie można odtworzyć tego z klangiem (Apple LLVM wersja 4.2 (clang-425.0.28) lub gcc (i686- apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1) –

Odpowiedz

9

Zobacz comp.Lang.c FAQ, 11.19:

Under ANSI C, the text inside a "turned off" #if, #ifdef, or #ifndef must still consist of "valid preprocessing tokens." This means that the characters " and ' must each be paired just as in real C code, and the pairs mustn't cross line boundaries.

1

Preprocesor działa na poziomie tokena, a literał łańcuchowy jest traktowany jako pojedynczy token. Preprocesor ostrzega, że ​​masz nieważny token.

Zgodnie ze standardem C99, token przerób jest jedną z tych rzeczy:

  • header-name
  • identy fi er
  • pp numer
  • charakter stałego
  • string-dosłowny
  • interpunkcja
  • każda nie-biała spacja które nie mogą być jednym z powyżej

Norma również mówi:

If a ' or a " character matches the last category, the behavior is undefined.

Rzeczy takie jak „oświadczenie” są nieważne z kompilatora C, ale jest to ważny znak, a eliminuje preprocesora ten token zanim dotrze do kompilatora.

2

Kompilacja musi przejść wiele cykli, zanim wygeneruje plik wykonywalny.

Nie jesteś jeszcze w kompilatorze. Twój pre-procesor zgłasza ten błąd. To nie sprawdza składni języka C, ale brakujące cytaty, nawiasy klamrowe i podobne rzeczy są błędami przed procesorem.

Po tej wstępnej procesora towarzysza, Twój kod trafi do kompilator C który wykryje błąd spodziewasz ...

0

Poza odpowiedzią Kevina, Incompatibilities of GCC mówi:

GCC complains about unterminated character constants inside of preprocessing conditionals that fail. Some programs have English comments enclosed in conditionals that are guaranteed to fail; if these comments contain apostrophes, GCC will probably report an error. For example, this code would produce an error:

#if 0 
You can't expect this to work. 
#endif 

The best solution to such a problem is to put the text into an actual C comment delimited by /*...*/ .

Powiązane problemy