【问题标题】:Representation and alignment requirements of enum types枚举类型的表示和对齐要求
【发布时间】:2018-10-08 19:12:19
【问题描述】:

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 的代码是否替换为符合 C 的 TAG?为什么或为什么不?

【问题讨论】:

  • 这不会编译。
  • 请用实际的编译代码更新您的问题。当您使用 enum 类型时,TAG 到底是什么? TAG 是 typedef 吗?宏?
  • @Stargateur 确实如此:ideone.com/fICYcM
  • @PSkocik #define TAG enum 不在 OP 中
  • 我不明白有什么令人惊讶的。

标签: c language-lawyer


【解决方案1】:

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

#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 类型也是如此,指向两种不同enum 类型的指针可能具有不同的实现。由于不允许对 enum 类型的前向引用,因此这不是问题。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 谢谢。我试过-Wall -Wextra。没有意识到我需要-pedantic
    • gcc 至少允许您像这样使用不完整的枚举和指向它们的指针,即使它不符合标准:gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/Incomplete-Enums.html
    • @PSkocik 始终使用 -pedantic(或 -pedantic-errors)。
    猜你喜欢
    • 1970-01-01
    • 2016-09-02
    • 1970-01-01
    • 1970-01-01
    • 2012-09-16
    • 2011-04-15
    • 2012-03-19
    • 1970-01-01
    相关资源
    最近更新 更多