2011-12-21 8 views
36

me encontré con este código en el cabeceras Linux, /usr/include/dirent.h:¿Cuál es el propósito de estos #define dentro de una enumeración?

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 
    }; 

Lo que se esta construcción para? - ¿por qué definir algo con una cadena idéntica, que luego se compilará con el valor int?

+0

Quizás solo hubo definiciones, y alguien agregó la enumeración más tarde. – Chris

Respuesta

21

Supongo que algún otro código puede verificar si uno de (o más de) estos valores enum se ha definido usando #ifdef.

+3

Lo mejor de ambos mundos: compruebe la definición con '# ifdef', pero sigue apareciendo como un nombre simbólico en la depuración. –

+0

Sí, este es probablemente el caso. Y como dice Chris en el comentario de la pregunta, tal vez sea legado: la enumeración se agregará más adelante, pero aún se necesita la capacidad de #ifdef sobre ellos. – GrahamW

+5

+1: este truco está [descrito en la documentación 'cpp' de' gcc'] (http://gcc.gnu.org/onlinedocs/gcc-4.6.2/cpp/Self_002dReferential-Macros.html#Self_002dReferential-Macros) como un uso útil de macros autorreferenciales. –

11

Mi (no educada) conjetura es que las declaraciones #define permiten las pruebas condicionales para ver si la constante se ha definido.

Por ejemplo:

#ifdef DT_UNKNOWN 
    // do something 
#endif 
24

Además de las otras respuestas que son muy buenas - me gustaría ir con ellos por la razón principal - el compilador podría generar advertencias o errores si intenta redefinir DT_UNKNOWN.

0

Usé -E y -dD argumentos (y también -fdump-tree-all) en gcc para ver la salida del preprocesador y no encontré nada útil. Así que supongo que este código no tiene ninguna funcionalidad más que mostrar los nombres simbólicos al depurar usando un depurador como gdb.

7

Creo que la respuesta de Luchian Grigore fue correcta.

Código

sin define:

#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; 
} 

De salida del compilador, no está claro por qué algunos línea de código dentro de enumeración no quiere construir:

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

Después añadimos tales define:

#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; 
} 

El compilador nos dice que DT_UNKNOWN se redefine y es un lugar donde se redefine:

[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 
Cuestiones relacionadas