2011-12-21 104 views
36

我发现这个代码的Linux头,/usr/include/dirent.h:这些#define在枚举中的用途是什么?

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

这是什么构建? - 为什么要定义一个相同的字符串,然后编译为int值?

+0

也许只有定义,有人在以后添加枚举。 – Chris 2011-12-21 10:58:00

回答

21

我的猜测是,其他代码可以检查是否有一个(或更多)这些枚举值已经使用#ifdef定义。

+3

两全其美 - 用#ifdef检查定义,但仍然显示为调试中的符号名称。 – 2011-12-21 10:58:32

+0

是的,这可能是这种情况。正如克里斯在对这个问题的评论中所说的那样,也许这是遗留问题 - 枚举被稍后添加,但仍然需要对它们进行#ifdef的能力。 – GrahamW 2011-12-21 11:02:39

+5

+1:这个技巧是[在gcc的'cpp'文档中描述](http://gcc.gnu.org/onlinedocs/gcc-4.6.2/cpp/Self_002dReferential-Macros.html#Self_002dReferential-Macros )作为自引用宏的有用用法。 – 2011-12-21 18:36:05

11

我的(未受教育的)猜测是#define语句允许条件测试查看该常量是否已被定义。

例如:

#ifdef DT_UNKNOWN 
    // do something 
#endif 
24

而且有很好的其他答案 - 我会跟他们一起去的主要原因 - 如果试图重新定义DT_UNKNOWN编译器可能会产生警告或错误。

0

我用-E-dD的参数(还有-fdump-tree-all)在gcc中看到预处理器的输出,发现没有用处。所以我猜这个代码没有任何功能,除了在使用像gdb这样的调试器进行调试时显示符号名称。

7

我认为Luchian Grigore的回答是正确的。

代码,而无需定义:

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

后,我们添加这样的定义:

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

从编译器的输出为什么里面列举一些代码行并不想建立目前还不清楚

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

编译器会告诉我们,DT_UNKNOWN被重新定义并被重新定义的地方:

[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