【问题标题】:Zero size struct零大小结构
【发布时间】:2012-06-10 19:23:28
【问题描述】:

我注意到,当使用 GCC 4.6 编译时,sizeof(Foo) 为 0,sizeof(Bar) 为 1。由于某种原因,将空数组添加到空结构中使其大小为 0。我认为这两个结构的大小必须是相同的。这是怎么回事?

struct Foo
{
    char x[];
};

struct Bar {};

【问题讨论】:

  • 这很奇怪,sizeof 永远不会是 0...
  • @K-ballo:对于像char x[] 这样的灵活数组,sizeof 为 0。
  • @K-ballo 不,它在 C99 以来的标准中。但是具有灵活数组成员的结构必须有多个命名成员。
  • @K-ballo 来自gcc extension docs灵活数组成员的类型不完整,因此可能无法应用 sizeof 运算符。作为零长度数组的原始实现的一个怪癖,sizeof 的计算结果为零。
  • gcc 4.2 here 报告编译器错误:error: flexible array member in else empty struct,这与扩展文档中的简介一致。

标签: c++ c gcc


【解决方案1】:

C 标准不允许 struct 声明。 n1570中的6.7.2.1(8):

如果 struct-declaration-list 不包含任何命名成员,无论是直接还是通过匿名结构或匿名联合,则行为未定义。

和第 18 段在同一节中:

作为一种特殊情况,具有多个命名成员的结构的最后一个元素可能具有不完整的数组类型;这称为灵活数组成员。在大多数情况下,灵活的数组成员被忽略。特别是,结构的大小就像省略了灵活数组成员一样,只是它的尾部填充可能比省略所暗示的要多。

(强调我的)

C++ 中不允许灵活的数组成员,因此代码也不是有效的 C++。

由于它不是有效代码,sizeof 报告的这些值是没有意义的。

【讨论】:

    【解决方案2】:

    sizeof 运算符永远不会产生 0,即使对于空类也是如此。

    如你所见here on msdn

    此外,msdn 声明:

    sizeof 运算符不能与以下操作数一起使用:

    • 函数。 (但是,sizeof 可以应用于指向函数的指针。)
    • 位域。
    • 未定义的类。
    • 类型 void。
    • 动态分配的数组。
    • 外部数组。
    • 类型不完整。
    • 带括号的不完整类型名称。

    【讨论】:

      【解决方案3】:

      C 和 C++ 不允许大小为零的对象。

      gcc 确实支持它们作为扩展。如果您使用正确的选项进行编译,例如

      gcc -std=c99 -pedantic -Wall -Wextra
      

      gcc 至少会警告你它们; g++ 也有类似的选项。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-12-24
        • 1970-01-01
        • 1970-01-01
        • 2012-12-07
        • 1970-01-01
        • 1970-01-01
        • 2015-11-26
        相关资源
        最近更新 更多