C-枚举长度的数组大小会产生汇编误差



请查看下面的代码,

此代码良好:

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吗?有人请澄清。

static char* const names[nr_names]是VLA,因为 nr_names不是恒定的表达式,而是(非const) int。当然,在这个简短的示例中,它总是等于NUM_IDS,但您仍然无法做到。


在无关的侧面注释上,建议将char定义为const,因为它是程序的二进制文件的一部分(在C 中,它不会让您将其具有non-const):

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

问题是不允许VLA具有静态存储持续时间

引用ISO 9899 6.7.5.2阵列声明器

如果将标识符声明为具有静态存储的对象 持续时间,它不得具有可变长度阵列类型。

因此,您不允许您一般声明静态VLA。因为nr_names不是恒定的,所以您不允许在第二个代码中使用静态。

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

第二个代码的另一个问题是不能初始化VLA。

我引用ISO 9899 6.7.8初始化

要初始化的实体的类型应为未知的数组 大小或不是可变长度阵列类型

的对象类型

最新更新