2012-06-11 2 views
5

Si consideri il seguente programma C (ignorare il numero doppio effetto collaterale):Macro di espansione per le macro con argomenti contro variabili con lo stesso nome

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

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

Il preprocessore GCC trasforma questo in:

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

Che è molto bello, dal momento che non devi preoccuparti di collisioni involontarie tra max e max(). Il GCC manual dice:

Una macro simile a una funzione viene espansa solo se il suo nome appare dopo una coppia di parentesi. Se scrivi solo il nome, è rimasto solo

Questo standardizzato o solo qualcosa per convenzione?

risposta

5

Sì, il comportamento qui è ben definito.

La macro max è una macro simile a una funzione (ad esempio, quando la si definisce, il suo nome viene immediatamente seguito da una parentesi chiusa e accetta argomenti).

Un utilizzo di max in seguito nel codice è solo un'invocazione di quella macro se l'utilizzo di max è seguito da una parentesi sinistra. Quindi, questi non avrebbero invocato la macro max:

int max; 
max = 42; 

Ma questi sarebbero tutti richiamare la macro max:

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

(Si noti che l'ultima riga è mal formata perché il numero di argomenti non lo fa corrisponde al numero di parametri, ma è comunque una chiamata alla macro e causerebbe un errore di compilazione)

Questo comportamento è richiesto dallo standard C langauge. C99 §6.10.3/10 stabilisce che dopo una macro funzione simile è stato definito,

Ogni successiva istanza del nome di macro funzione simile seguita da una ( come token successivo preelaborazione introduce la sequenza di token preelaborazione viene sostituito dall'elenco di sostituzione nella definizione (un'invocazione della macro).

+0

Sono confuso. Sembra che gcc abbia onorato la macro massima e non abbia chiamato la funzione max reale. – octopusgrabbus

+0

@octopusgrabbus: quale funzione 'max'? –

+0

Trovato la parte rilevante nel manuale GCC, ma non so ancora se questo è standardizzato o solo una convenzione informale – mensi