2016-05-01 14 views
11

, ho visto il codice sorgente come lo scorrere. Possiamo usare #define in una funzione? Come funziona? (Ulteriori informazioni: questi codice sono ciò che copio da openvswitch codice sorgente):È possibile utilizzare #define all'interno di una funzione? Per esempio,

void * 
ofputil_put_action(enum ofputil_action_code code, struct ofpbuf *buf) 
{ 
switch (code) { 
case OFPUTIL_ACTION_INVALID: 

#define OFPAT13_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) case OFPUTIL_##ENUM: 
#include "ofp-util.def" 
    OVS_NOT_REACHED(); 

#define OFPAT10_ACTION(ENUM, STRUCT, NAME)     \ 
case OFPUTIL_##ENUM: return ofputil_put_##ENUM(buf); 
#define OFPAT11_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME)  \ 
case OFPUTIL_##ENUM: return ofputil_put_##ENUM(buf); 
#define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME)  \ 
case OFPUTIL_##ENUM: return ofputil_put_##ENUM(buf); 
#include "ofp-util.def" 
} 
OVS_NOT_REACHED(); 
} 

#define OFPAT10_ACTION(ENUM, STRUCT, NAME)      \ 
void              \ 
ofputil_init_##ENUM(struct STRUCT *s)      \ 
{               \ 
    memset(s, 0, sizeof *s);        \ 
    s->type = htons(ENUM);         \ 
    s->len = htons(sizeof *s);        \ 
}               \ 
                  \ 
struct STRUCT *            \ 
ofputil_put_##ENUM(struct ofpbuf *buf)      \ 
{               \ 
    struct STRUCT *s = ofpbuf_put_uninit(buf, sizeof *s); \ 
    ofputil_init_##ENUM(s);         \ 
    return s;            \ 
} 
#define OFPAT11_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) \ 
OFPAT10_ACTION(ENUM, STRUCT, NAME) 
#define OFPAT13_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) \ 
OFPAT10_ACTION(ENUM, STRUCT, NAME) 
#define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME)   \ 
void              \ 
ofputil_init_##ENUM(struct STRUCT *s)      \ 
{               \ 
    memset(s, 0, sizeof *s);        \ 
    s->type = htons(OFPAT10_VENDOR);      \ 
    s->len = htons(sizeof *s);        \ 
    s->vendor = htonl(NX_VENDOR_ID);      \ 
    s->subtype = htons(ENUM);        \ 
}               \ 
                  \ 
struct STRUCT *            \ 
ofputil_put_##ENUM(struct ofpbuf *buf)      \ 
{               \ 
    struct STRUCT *s = ofpbuf_put_uninit(buf, sizeof *s); \ 
    ofputil_init_##ENUM(s);         \ 
    return s;            \ 
} 
#include "ofp-util.def" 
+14

Voglio sapere che cosa stava fumando il programmatore quando è stato scritto quel codice –

+2

@EdHeal http://www.incrediblethings.com/wp-content/uploads/2015/03/squid-blunt-1.jpg –

+1

Descrivi cosa vorresti realizzare usando #define.Se la domanda è "verrà compilato un programma con un #define all'interno di una definizione di funzione?" allora la risposta è sì. – Jfevold

risposta

16

#defineè una direttiva del preprocessore: viene utilizzato per generare l'eventuale codice C++ prima che venga gestita al compilatore che genererà un file eseguibile. Pertanto il codice come:

for(int i = 0; i < 54; i++) { 
    #define BUFFER_SIZE 1024 
} 

è non eseguito 54 volte (a livello preprocessore): il preprocessore corre semplicemente sulla spira for (non sapendo cosa un ciclo for è), vede una dichiarazione definire, collegate 1024 con BUFFER_SIZE e continua. Fino a quando raggiunge il fondo del file.

È possibile scrivere #define ovunque poiché il preprocessore non è realmente a conoscenza del programma stesso.

7

sicuro che questo è possibile. Lo #define viene elaborato dal preprocessore prima che il compilatore esegua qualcosa. È una semplice sostituzione di testo. Il preprocessore non sa nemmeno se la linea di codice è dentro o fuori una funzione, una classe o qualsiasi altra cosa.

A proposito, in genere viene considerato uno stile non valido per definire le macro del preprocessore in C++. La maggior parte delle cose per cui sono utilizzate può essere meglio realizzata con i modelli.

1

Puoi usare #define ovunque tu voglia. Non ha conoscenza delle funzioni e non è vincolato dal loro scopo. Mentre il preprocessore esegue la scansione del file dall'alto verso il basso, elabora #define s come li vede. Non essere ingannato (da codice sciocco come questo!) Nel pensare che lo #define sia in qualche modo elaborato solo quando viene chiamata la funzione; non è.

2

Come funziona? Tutti i file C/C++ vengono prima elaborati da ... il preprocessore .

Non sa nulla sulla sintassi C o C++. Sostituisce semplicemente THIS_THING con ANOTHER THING. Ecco perché è possibile inserire un #define anche in funzioni.

2

Sicuro. #define viene gestito dal preprocessore che si verifica molto prima che il compilatore abbia un senso di righe di codice all'interno di funzioni, all'interno di liste di parametri, all'interno di strutture dati, ecc.

Poiché il preprocessore non ha concetto di funzioni C++, significa anche che non esiste un ambito naturale per le definizioni di macro. Pertanto, se si desidera riutilizzare un nome di macro, è necessario #undef NAME per evitare avvisi.

2

È possibile utilizzarlo all'interno di una funzione, ma non è collegato alla funzione. Quindi, nel tuo esempio, la seconda definizione di una macro sarà una ridefinizione e genererà un errore. È necessario utilizzare #undef per eliminarli prima.

+0

Non sono sicuro di introdurre * scope * in questo. Poiché il preprocessore semplicemente (pre) elabora il file come testo normale, dall'alto verso il basso, tutto ciò che vede sono # define, items to replace e yes, # undef's. Non è * consapevole * delle 'funzioni' - puoi # definire e #undef più volte all'interno (o all'esterno) di una singola funzione. – usr2564301

Problemi correlati