2012-06-11 13 views
5

Rozważmy następujący C programu (Ignore podwójnego efektów ubocznych wydania)Makro ekspansja makra z argumentami vs. zmiennych o tej samej nazwie

#define max(a, b) (a>b?a:b) 

int main(void){ 
    int max = max(5,6); 
    return max; 
} 

Preprocesor GCC zamienia to na:

int main(void){ 
    int max = (5>6?5:6); 
    return max; 
} 

Co jest całkiem miłe, ponieważ nie musisz się martwić niezamierzonymi kolizjami między max a max(). GCC manual mówi:

Makro podobne do funkcji jest rozszerzane tylko wtedy, gdy jego nazwa pojawia się z parą nawiasów po nim. Jeśli napiszesz tylko imię i nazwisko, zostaje ono pozostawione samo sobie

Czy to jest standaryzowane, czy po prostu wykonane według konwencji?

Odpowiedz

5

Tak, zachowanie tutaj jest dobrze zdefiniowane.

Twoje makro max jest makrem podobnym do funkcji (to znaczy, gdy je definiujesz, jego nazwa jest zaraz po nim lewym nawiasem i przyjmuje argumenty).

Użycie max później w kodzie jest tylko wywołaniem tego makra, jeśli po max następuje lewy nawias. Tak, to nie będzie podniesienia zarzutu max makro:

int max; 
max = 42; 

Ale to byłoby wszystko wywołać makro maks:

max(1, 2) 
max (1, 2) 
max 
(
    1, 2 
) 
max() 

(Zauważ, że ostatni wiersz jest źle sformułowane, ponieważ liczba argumentów nie pasuje do liczby parametrów, ale nadal jest to makroinwazyjne wywołanie błędu kompilacji.)

To zachowanie jest wymagane przez standard C langauge. C99 §6.10.3/10 stwierdza się, że po tym jak funkcja makro został zdefiniowany,

Każdy kolejny przykład nazwy funkcja makro-jak następnie ( jako następnego przetwarzania wstępnego znak przedstawia sekwencję znaczników preprocesora zastąpiona przez listę zastępczą w definicji (wywołanie makra).

+0

Jestem zdezorientowany. Wygląda na to, że gcc uznał makra max, a zamiast tego wywołał prawdziwą funkcję max. – octopusgrabbus

+0

@octopusgrabbus: Jaka funkcja "max"? –

+0

Znaleziono odpowiednią część w podręczniku GCC, ale nadal nie wiem, czy jest to standaryzacja, czy tylko nieformalna konwencja. – mensi

Powiązane problemy