2015-08-24 16 views
5

Hi Questo è il codice legale per il compilatore che uso:Come implementare una macro in C

#use delay(clock=4M) 

ora ho bisogno di sostituire le staffe all'interno del testo clock=4M con una macro. La cifra 4 potrebbe essere qualsiasi cifra, dovrebbe essere modificabile. Ho provato con questo

#define CLOCK_SPEED(x)  clock=xM 

sbagliando di poco lavoro.

+1

Definire "non ha funzionato". Cosa ti aspettavi * e cosa hai * ottenuto *? Detto questo, hai bisogno di una seconda macro nella catena che espande 'x' prima di espandere' clock = xM'. –

+0

Le domande per la ricerca del debug ("perché non funziona questo codice?") Devono includere il comportamento desiderato, un problema specifico o un errore e il codice più breve necessario per riprodurlo nella domanda stessa. Le domande senza una chiara affermazione di problemi non sono utili agli altri lettori. Vedi: Come creare un [mcve]. – Olaf

+1

L'intento dell'OP è abbastanza chiaro per me, così come il suo problema reale e il modo di risolverlo. –

risposta

13

Quello che vuoi è il preprocessore concatenation operator, ##.

#define CLOCK(x) clock=x##M 

void some_function() { 
     CLOCK(4); 
} 

Il risultato:

tmp$ cpp -P test.c 
void some_function() { 
clock=4M; 
} 

Una nota a parte, le macro come queste sono spesso la causa di bug difficili da trovare. È usually recommended to write them like this:

#define CLOCK(x) do { clock=x##M; } while(0) 
+0

Sì, funziona. Farò clic per accettare la risposta non appena sono autorizzato a farlo. –

+0

In che modo la tua raccomandazione rende più facile trovare gli errori? –

+1

Non lo fa - riduce il rischio di introdurli. Immagina una macro come '#define STUFF (x) a = x; b = x'. Usato chiaramente, va bene: 'STUFF (x);' andrà bene. Tuttavia, ecco uno scenario peggiore: 'if (x> 3) STUFF (x);'. Questo compila, ma pre-processa in 'if (x> 3) a = x; b = x' - quindi 'b' sarà * sempre * impostato! Questo problema non è affatto ovvio quando si legge il codice sorgente, quindi rintracciare questo problema potrebbe essere difficile. È più probabile che questo tipo di problema si verifichi quando qualcuno modifica una macro di istruzione singola in una macro con più istruzioni. Ed è per questo che usare do-while-0 è una buona abitudine. –