【问题标题】: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,不。未定义的行为只是意味着标准没有强加任何要求。
  • 我同意,不可能为不正确的语言使用编写要求。但就我个人而言,“未定义的行为”是关于编写为“糟糕的编程示例”的程序,而不是关于使用“糟糕的编程示例”做任何事情的编译器

标签: c visual-c++ gcc struct c99


【解决方案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。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-05
  • 2020-09-06
  • 1970-01-01
  • 2011-11-02
  • 2011-02-25
  • 1970-01-01
相关资源
最近更新 更多