C99 语言中具有未命名成员的结构的正确行为是啥?
Posted
技术标签:
【中文标题】C99 语言中具有未命名成员的结构的正确行为是啥?【英文标题】:Which is the correct behavior of the struct with unnamed member in C99 language?C99 语言中具有未命名成员的结构的正确行为是什么? 【发布时间】:2015-04-15 12:03:30 【问题描述】:#include <stdio.h>
struct s int;;
int main()
printf("Size of 'struct s': %i\n", sizeof(struct s));
return 0;
Microsoft C 编译器 (cl.exe) 不想编译此代码。
error C2208: 'int' : no members defined using this type
GNU C 编译器 (gcc -std=c99) 编译此代码...
warning: declaration does not declare anything
...并显示结果:
Size of 'struct s': 0
这意味着 gcc 中的struct s
是完整类型,不能重新定义。
这是否意味着完整类型的大小可以为零?
另外,如果这个声明声明了完整的结构,那么消息declaration does not declare anything
是什么意思?
这是struct s
是 (gcc -std=c99) 中的完整类型的证明。
#include <stdio.h>
struct s int;;
struct S
struct s s; // <=========== No problem to use it
;
int main()
printf("Size of 'struct s': %i\n", sizeof(struct s));
return 0;
【问题讨论】:
我认为是gcc的特性,而不是c99的特性 @VolAnd。谢谢。这是因为对我来说,语言规范中的undefined behavior
一词是无法理解的。运行时未定义的行为或编译时未定义的行为。
“警告:声明没有声明任何东西”是关于编译时间的。未定义的行为与运行时有关。
@VolAnd Er,不。未定义的行为只是意味着标准没有强加任何要求。
我同意,不可能为不正确的语言使用编写要求。但就我个人而言,“未定义的行为”是关于编写为“糟糕的编程示例”的程序,而不是关于使用“糟糕的编程示例”做任何事情的编译器
【参考方案1】:
根据 C 标准,该行为未定义。
J.2 未定义行为:
在以下情况下行为未定义: .... — 结构或联合的定义没有任何命名成员(包括通过匿名结构和联合间接指定的那些)(6.7.2.1)。
struct s int;;
等同于struct s ;
(无成员),GCC 允许将其作为extension。
struct empty ;
结构的大小为零。
这使上述程序成为特定于编译器的程序。
【讨论】:
好的。结构行为或编译器行为的行为未定义?没问题,但是为什么 MS C 编译器不希望编译具有未定义行为的代码。什么行为更好? MSVC 还是 GCC? @mezoni;在这种情况下,结果将是特定于编译器的。 谢谢!将此添加到完整性的答案中。【参考方案2】:大小为 0 的类型不是标准的。那是一个 gcc 扩展。
如果你将 -pedantic-errors 添加到你的 gcc 编译行,那么它不会编译。
【讨论】:
嗯,令人惊讶的是,即使使用 -ansi -pedantic,gcc 仍然可以为我编译。 感谢-pedantic
。
@mezoni 强制保证编译器错误的唯一方法是-pedantic-errors
。顺便说一句,-ansi
仅表示 C89/90。以上是关于C99 语言中具有未命名成员的结构的正确行为是啥?的主要内容,如果未能解决你的问题,请参考以下文章