2012-10-02 11 views
7

All'interno dei sorgenti del kernel Linux vedo che, all'interno delle enumerazioni, esiste anche una definizione con lo stesso nome dell'elemento enum. Esempio in linux/rtnetlink.h abbiamo:definisce all'interno enum

enum { 
     RTM_BASE  = 16, 
#define RTM_BASE  RTM_BASE 

     RTM_NEWLINK  = 16, 
#define RTM_NEWLINK  RTM_NEWLINK 
     RTM_DELLINK, 
#define RTM_DELLINK  RTM_DELLINK 
... 

Qual è la ragione di questo? Non riesco a capire come viene usato.

Grazie

risposta

2

Un'altra ipotesi: questa macro potrebbe consentire di rinominare una voce dell'enumerazione senza interrompere altro codice. Cambiare

enum { 
     RTM_BASE  = 16, 
#define RTM_BASE  RTM_BASE 

a

enum { 
     RTM_BASE_NEW_NEW_NEW  = 16, 
#define RTM_BASE  RTM_BASE_NEW_NEW_NEW 

Un utente potrebbe ancora usare RTM_BASE.

+0

'RTM_BASE = RTM_BASE_NEW_NEW_NEW' funzionerebbe altrettanto bene, senza definire. –

5

Una cosa che mi veniva in mente è che si può verificare l'esistenza molto della enum tramite la macro:

#ifdef RTM_BASE 
int flag = RTMBASE; 
#else 
int flag = 0; 
#endif 

Non ho idea se questo è quello che sta succedendo, anche se.

+0

Sì, è esattamente quello che stavo per scrivere dopo aver finito il mio panino. È l'unico scopo per cui riesco a vedere questo davvero utile –

+0

Utile! Ma guardando le fonti, sembra che le definizioni non vengano usate in questo modo. Grazie. – MirkoBanchi

+1

Non avrebbe senso farlo nei sorgenti del kernel, ma ha senso nelle applicazioni dello spazio utente che potrebbero dover funzionare su più versioni del kernel, in cui le funzionalità potrebbero essere o meno presenti. –

3

Un'altra cosa che questi #define s ottengono, oltre a consentire al vecchio codice di continuare i vecchi nomi nel caso in cui i nomi delle costanti di enum siano cambiati e nel controllarne la definizione, è di impedire che altri codici definiscano questi simboli.

#include <linux/rtnetlink.h> 
// for some reason, the author thinks 
#define RTM_BASE 17.3f 
// is a good idea 

non si compila.

+0

Questa risposta è secondo me giusta. Le altre 2 risposte sembrano piuttosto originali per me. Questo ha il potenziale per scoprire conflitti reali, difficili da trovare, che sono abbastanza facili da fare. –