枚举类型的表示形式和对齐要求

时间:2018-10-08 19:12:20

标签: c language-lawyer

6.2.5p28提到

  

...所有指向结构类型的指针都应具有相同的指针   彼此之间的表示和对齐要求。所有指针   联合类型应具有相同的表示形式和对齐方式   彼此需求。指向其他类型的指针不必具有   相同的表示或对齐要求。

我相信正是这一段允许使用以下代码:

TAG x;

void take(TAG x* X) { (void)X; }

int main() 
{
  TAG x *xp = 0;
  take(xp);
}

TAG被定义为扩展为structunion关键字的宏时进行编译。 但是,它也是compiles (tcc, gcc, clang) when TAG is defined as a macro expanding to the enum keyword

鉴于上述情况,用enum代替TAG符合C的代码吗?为什么或为什么不呢?

2 个答案:

答案 0 :(得分:3)

这是您在评论中提供的链接中的代码:

#define TAG enum
TAG x;

void take(TAG x* X) { (void)X; }

int main() {
  TAG x *xp = 0;
  take(xp);
};

(名称“ TAG”具有误导性。标签是标识符;例如,在enum foo {a, b, c}中,标签foo。)

这是无效的。当我使用gcc -std=c11 -pedantic-errors进行编译时,我得到:

c.c:2:5: error: ISO C forbids forward references to 'enum' types [-Wpedantic]
 TAG x;
     ^
c.c:4:15: error: ISO C forbids forward references to 'enum' types [-Wpedantic]
 void take(TAG x* X) { (void)X; }
               ^
c.c: In function 'main':
c.c:7:7: error: ISO C forbids forward references to 'enum' types [-Wpedantic]
   TAG x *xp = 0;
       ^
c.c: At top level:
c.c:9:2: error: ISO C does not allow extra ';' outside of a function [-Wpedantic]
 };
  ^

由于允许向前引用struct类型,所以所有指向结构的指针都必须具有相同的表示形式,因为编译器在看到指针类型时可能未看到完整的结构定义。

union类型也是如此。对于enum类型, not 相同,并且指向两个不同enum类型的指针可能具有不同的实现。由于不允许向前引用enum类型,所以这不是问题。

答案 1 :(得分:1)

与许多其他问题一样,该问题的答案在于启用了警告的情况下运行编译器

$ gcc example.c -Wall -pedantic
example.c:3:5: warning: ISO C forbids forward references to ‘enum’ types [-Wpedantic]
 TAG x;
     ^
example.c:5:15: warning: ISO C forbids forward references to ‘enum’ types [-Wpedantic]
 void take(TAG x* X) { (void)X; }
               ^
example.c: In function ‘main’:
example.c:9:7: warning: ISO C forbids forward references to ‘enum’ types [-Wpedantic]
   TAG x *xp = 0;
       ^
example.c: At top level:
example.c:11:2: warning: ISO C does not allow extra ‘;’ outside of a function [-Wpedantic]
 };