2011-12-21 9 views
36

znalazłem ten kod w nagłówkach Linux, /usr/include/dirent.h:Jaki jest cel tych # definicji w ramach wyliczenia?

enum 
    {  
    DT_UNKNOWN = 0, 
# define DT_UNKNOWN DT_UNKNOWN 
    DT_FIFO = 1, 
# define DT_FIFO DT_FIFO 
    DT_CHR = 2, 
# define DT_CHR  DT_CHR 
    DT_DIR = 4, 
# define DT_DIR  DT_DIR 
    DT_BLK = 6, 
# define DT_BLK  DT_BLK 
    DT_REG = 8, 
# define DT_REG  DT_REG 
    DT_LNK = 10, 
# define DT_LNK  DT_LNK 
    DT_SOCK = 12, 
# define DT_SOCK DT_SOCK 
    DT_WHT = 14 
# define DT_WHT  DT_WHT 
    }; 

Co jest tego konstruktu za? - po co definiować coś za pomocą identycznego ciągu znaków, który następnie zostanie skompilowany do wartości int?

+0

Może były tylko definicje, a ktoś dodał wyliczenie później. – Chris

Odpowiedz

21

Domyślam się, że jakiś inny kod może następnie sprawdzić, czy jednego (lub więcej) wartości te zostały zdefiniowane enum przy użyciu #ifdef.

+3

Najlepsze z obu światów - sprawdź definicji z '# ifdef', ale nadal pokazuje się jako symboliczne nazwy w debugowania. –

+0

Tak, prawdopodobnie tak jest. I jak mówi Chris w komentarzu do pytania, być może jest to dziedzictwo - enum dodaje się później, ale wciąż jest potrzebna możliwość #ifdef na nich. – GrahamW

+5

+1: Ta sztuczka jest [opisane w 'dokumentacji cpp' gcc' za] (http://gcc.gnu.org/onlinedocs/gcc-4.6.2/cpp/Self_002dReferential-Macros.html#Self_002dReferential-Macros) jako użyteczne użycie makr z samoodprowadzaniem. –

11

My (bez wykształcenia) Domyślam się, że oświadczenia #define umożliwić testy warunkowe, czy stała została zdefiniowana.

Na przykład:

#ifdef DT_UNKNOWN 
    // do something 
#endif 
24

Oprócz innych odpowiedzi, które są bardzo dobre - pójdę z nimi do głównego powodu - kompilator może generować ostrzeżenia lub błędy podczas próby przedefiniowania DT_UNKNOWN.

0

Użyłem -E i -dD argumentów (a także -fdump-tree-all) w gcc, aby zobaczyć wyjście preprocesora i nie znalazłem nic użytecznego. Domyślam się, że ten kod nie ma żadnej funkcjonalności poza wyświetlaniem symbolicznych nazw podczas debugowania przy użyciu debuggera takiego jak gdb.

7

Myślę, że odpowiedź Luchian GRIGORE była prawidłowa.

kod bez określa:

#include <stdio.h> 

// Defined somewhere in headers 
#define DT_UNKNOWN 0 

enum 
{ 
    DT_UNKNOWN = 0, 
    DT_FIFO = 1, 
}; 

int main(int argc, char **argv) 
{ 
    printf("DT_UNKNOWN is %d\n", DT_UNKNOWN); 
    return 0; 
} 

Od wyjściu kompilatora nie jest jasne, dlaczego niektórzy wiersz kodu wewnątrz wyliczenia nie chce budować:

[email protected]:~/tmp$ gcc -Wall ./main.c 
./main.c:7: error: expected identifier before numeric constant 

Po dodamy takie określa:

#include <stdio.h> 

// Defined somewhere in headers 
#define DT_UNKNOWN 0 

enum 
{ 
    DT_UNKNOWN = 0, 
    # define DT_UNKNOWN DT_UNKNOWN 
    DT_FIFO = 1, 
    # define DT_FIFO DT_FIFO 
}; 

int main(int argc, char **argv) 
{ 
    printf("DT_UNKNOWN is %d\n", DT_UNKNOWN); 
    return 0; 
} 

Kompilator powie nam, że DT_UNKNOWN jest przedefiniowane i miejsce, w którym jest na nowo zdefiniowane:

[email protected]:~/tmp$ gcc -Wall ./main2.c 
./main2.c:7: error: expected identifier before numeric constant 
./main2.c:8:1: warning: "DT_UNKNOWN" redefined 
./main2.c:3:1: warning: this is the location of the previous definition