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 语言中具有未命名成员的结构的正确行为是啥?的主要内容,如果未能解决你的问题,请参考以下文章

C# 中具有表达式主体的私有成员的标准命名约定是啥[关闭]

没有命名成员的结构在哪里有用?

C99 标准在哪里说有符号整数溢出是未定义的行为?

c语言里面的结构体是啥意思

在C语言中,FUNC是啥意思?

在C语言中,FUNC是啥意思?