6.2.5p28提到
...所有指向结构类型的指针应具有彼此相同的表示和对齐要求。所有指向联合类型的指针应具有彼此相同的表示和对齐要求。指向其他类型的指针不需要具有相同的表示或对齐要求。
我相信这段代码允许这样的代码:
TAG x;
void take(TAG x* X) { (void)X; }
int main()
{
TAG x *xp = 0;
take(xp);
}
在将TAG
定义为展开到struct
或union
关键字的宏时进行编译。然而,它也是compiles (tcc, gcc, clang) when TAG
is defined as a macro expanding to the enum
keyword。
鉴于上述情况,使用enum
的代码是否取代了符合TAG
的C?为什么或者为什么不?
发布于 2018-10-09 03:33:55
以下是你在评论中给出的链接的代码:
#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
类型的正向引用,所以这不是问题。
发布于 2018-10-09 03:30:55
与许多其他问题一样,这个问题的答案在于使用启用了警告的运行编译器的。
$ 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]
};
https://stackoverflow.com/questions/52708679
复制相似问题