枚举导致多重定义的错误,而typedef枚举不是

时间:2014-07-22 08:39:29

标签: c enums typedef

我正在恭维C代码。

说我有头文件,A.h包含一个枚举。 我将此文件包含在2个c文件中--B.c和C.c

B.c:

#include A.h
//....other code...

C.C

#include A.h
//....other code...

当A.h包含枚举时:

A.H

#ifndef A_H
#define A_H

enum my_enum {

  //...enum content...

} my_enum;

//...other code...

#endif   

当这样定义时,我从编译器得到一个'符号'my_enum“多重定义”错误,这是可以理解的 - 因为我在头文件中定义了枚举。

然而,当我输入enum -

时,这不会发生

A.H

#ifndef A_H
#define A_H

typedef enum my_enum {

  //...enum content...

} my_enum;

//...other code...

#endif   

当然,无论.c文件中的代码是什么(除了包括A.h)

,都会发生这种情况

这背后的原因是什么? 当我输入枚举时,为什么它不是多重定义?

3 个答案:

答案 0 :(得分:4)

enum my_enum {

  //...enum content...

} my_enum;

my_enum这里不是类型,而是enum my_enum类型的变量。将其包含在标题中会导致变量my_enum的多重定义。

typedef enum my_enum {

  //...enum content...

} my_enum;

my_enum这是一个类型,而不是变量。它的类型与enum my_enum相同。这是typedef

的功能

答案 1 :(得分:1)

在C中有不同的名称空间 我们有这样的干扰规则" (或不)标识符:

  • 不同范围中的标识符不在混淆中。
  • 相同范围中的标识符,但属于不同的名称空间不会发生冲突。

这些名称空间是:

  1. 普通标识符(指定对象,函数,typedef名称和枚举常量)。
  2. enumstructunion标记。
  3. struct/union个成员。
  4. 标签(与goto一起使用)。
  5. 因此,例如,由于typedef名称,enum tagss,struct成员和标签都位于不同的名称空间,因此以下代码没有任何冲突:

      int main(void)   // "x" is always in diffrent name spaces and/or scopes
      {
           typedef struct { struct { float x; } x; }  x;
           enum x { zero = 0 } value = zero;
    
           x:    // Label
    
          if (value != 0)
               goto x;
    
          { // This block is another scope
    
              typedef enum x { one = 1 } x;
              x w = one;
          }
      }
    

    供参考,请参阅C标准文件的第6.2.3节Standard C99, TC3

答案 2 :(得分:0)

当你使用typedef时,它会将my_enum视为枚举的别名。

即。在这种情况下,my_enum表现为一种类型,而不是变量。

如果你不使用typedef它会多次声明..