【问题标题】:how sizeof empty enum is 4 in C++?在 C++ 中,空枚举的 sizeof 是 4 多少?
【发布时间】:2015-10-23 16:41:39
【问题描述】:

考虑以下程序(查看现场演示here

#include <iostream>
int main()
{
    enum days{}d;
    std::cout<<sizeof(d);
}

当使用 g++ 4.8.1 编译时,它会在我的本地机器上打印 4 作为输出。这里怎么占4个字节?在给定链接中的 gcc 6.0 上,我也使用了 `-pedantic-option 但它仍然可以正常编译。

那为什么在 C 语言中是不允许的呢?我在 gcc 4.8.1 中尝试了以下程序。 (见现场演示here

#include <stdio.h>
int main(void)
{
    enum days{}d;
    printf("sizeof enum is %u",sizeof(d));
}

编译器出现以下错误:

4   12  [Error] expected identifier before '}' token

5   36  [Error] 'd' undeclared (first use in this function)

5   36  [Note] each undeclared identifier is reported only once for each function it appears in

是否允许在 C++ 中有空枚举但在 C 中不允许?

【问题讨论】:

  • C++ 不是 C 的扩展,尽管很多时候它被混淆了。显然有一个非常广泛的共同点,但它们是具有不同规则的不同语言。
  • gcc 不会除了这个。 C++ 符合标准

标签: c++ c gcc enums


【解决方案1】:

C++ 不是 C。对于 C++,来自 [dcl.enum]:

对于底层类型不固定的枚举,底层类型是整型,可以 表示枚举中定义的所有枚举值。 [...] 使用哪种整数类型是实现定义的 作为基础类型,但基础类型不得大于int,除非 枚举器不能放入 intunsigned int。如果 enumerator-list 为空,则基础类型是就好像枚举有一个值为 0 的单个枚举器

所以枚举器的底层类型(决定它的大小)就好像它只有一个 0,尽管实际类型是实现定义的。它可能是 1(int8_t 当然可以容纳 0),但绝对不大于 4。在这种情况下,你得到 4,这是完全合理的。

对于 C,语法只需要一个枚举器。

【讨论】:

  • 你怎么知道枚举的大小就是底层类型的大小(假设这就是“确定”的意思)?我什至不确定后者是否提供了下限。
  • @Columbo 还会是什么?
  • 这并没有回答我的问题,而是提出了另一个问题。我只是希望你能找到我没有找到的报价。
  • 谁能把这个标准翻译成英文:“对于底层类型不固定的枚举”,“底层类型不固定”是什么意思?
  • @Columbo 是的,我没有看到任何具体的措辞,你是对的。只是如何有一个底层类型,它可以被提升到它,等等。但是,是的,我猜一个符合要求的实现可能会坚持 100 字节的填充......
【解决方案2】:

与 C 不同,C++ 允许空枚举。 [dcl.enum]/7:

如果 enumerator-list 为空,则底层类型就像 枚举有一个值为 0 的枚举数。

在您的情况下,基础类型(其大小通常也是枚举大小)实际上是实现定义的,尽管大多数编译器可能会选择int(并且不允许在这里选择更大的值):

由实现定义的整数类型用作 基础类型,但基础类型不得更大 比int 除非枚举器的值不能适合intunsigned int.


C 对“基础类型”有相同的要求(尽管 C 中不存在确切的概念),但它的语法首先不允许空枚举 - §6.7.2.2/1:

枚举器列表
     枚举器
     枚举器列表枚举器

【讨论】:

    【解决方案3】:

    你是对的。在 C 中不能有一个空的枚举数列表。但是在 C++ 中可以有它。见http://en.cppreference.com/w/c/language/enumhttp://en.cppreference.com/w/cpp/language/enum

    【讨论】:

      【解决方案4】:

      C11 standard 要求在枚举声明中至少有一个枚举器(第 6.7.2.2 节),主要部分复制如下:

      枚举说明符:
      枚举 标识符opt { 枚举器列表 }
      枚举 标识符opt { 枚举器列表 }
      枚举 标识符

      枚举器列表
      枚举器
      枚举器列表, 枚举器

      抱歉,格式有些不可靠,我试图尽可能接近地从(提议的)标准重新创建段落。

      【讨论】:

        【解决方案5】:

        在 C++ 中,大小为 4 字节,因为您的编译器选择 int 作为枚举的基础整数类型。显然sizeof(int) 在您的平台上是 4。在编译器世界中非常流行默认使用int 来表示枚举(除非需要更大的类型)。

        至于为什么它在 C 中是不允许的……嗯,在 C 中是不允许的,因为它在 C 中是不允许的。C 是一种完全不同的语言,有自己的语法规则。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-04-26
          • 2010-11-26
          • 2011-06-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-09
          相关资源
          最近更新 更多