【问题标题】:Array size of enum length gives compilation error枚举长度的数组大小会导致编译错误
【发布时间】:2019-07-21 03:48:38
【问题描述】:

看看下面的代码,

这段代码编译得很好:

enum ids {
    X,
    Y,
    NUM_IDS,
}

void some_func(void)
{
    static char* const names[NUM_IDS] = { "name X" , "name Y"};
}

但是,这段代码无法编译: 错误:“名称”的存储大小不是恒定的

enum ids {
    X,
    Y,
    NUM_IDS,
}

void some_func(void)
{
    int nr_names = NUM_IDS;
    static char* const names[nr_names] = { "name X" , "name Y"};
}

我想我误解了常量表达式的含义。是否以第二种方式成为C90中不存在的VLA?有人请澄清。

【问题讨论】:

  • 您不能拥有静态或全局 VLA
  • @Jabberwocky 为什么第二种情况是 VLA,但第一种不是?
  • 因为NUM_IDS 是一个编译时间常数。 nr_names 不是
  • 这就是为什么在 C++11 中引入constexpr
  • nr_names 直到运行时才知道。 static char* const names[nr_names] 在编译时需要一个数组大小。您希望 nr_names 在编译时具有什么值?

标签: c constants variable-length-array


【解决方案1】:

static char* const names[nr_names] 是一个 VLA,因为nr_names 不是一个常量表达式,而是一个(非常量)int。当然,在这个简短的示例中,它始终等于 NUM_IDS,但您仍然不能这样做。


在不相关的旁注中,建议将char 定义为const,因为修改它是行不通的,因为它是程序二进制文件的一部分(在 C++ 中,它不会让你没有它-const):

static const char* const names[NUM_IDS] = { "name X" , "name Y" };

【讨论】:

  • 好吧,如果您不想更改指针,那么在两个地方都有const 是有意义的。所以不一定是错的,只是缺少了另一个const
  • "无论哪种方式,char 都需要是 const:" --> 不,这里不需要。
  • 哦,哇,出于某种原因,我以为这是 C++。你是对的,它不需要。我会修复答案。
【解决方案2】:

问题是 VLA 不允许有静态存储时长

引用 ISO 9899 6.7.5.2 数组声明符

如果标识符被声明为具有静态存储的对象 持续时间,它不应具有可变长度数组类型。

因此,一般情况下,您不允许声明静态 VLA。因为nr_names 不是常量,所以不允许在第二个代码中使用静态。

第一个代码是正确的,因为NUM_IDS是常量表达式。

您的第二个代码的其他问题是无法初始化 VLA。

我引用 ISO 9899 6.7.8 初始化

要初始化的实体的类型应该是一个未知数组 大小或不是变长数组类型的对象类型

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-23
    • 2018-12-12
    • 1970-01-01
    • 2014-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-20
    相关资源
    最近更新 更多