【发布时间】:2019-01-17 11:21:43
【问题描述】:
我正在了解VLAs 并写了以下示例:
struct array_t{
const size_t length;
const char data[];
};
struct array_t *create(const size_t n, const char data[n]){
const size_t data_offset = offsetof(struct array_t, data);
struct array_t *array = malloc(data_offset + n * sizeof(char));
memcpy(&(array -> length), &n, sizeof(n));
memcpy(&(array -> data), data, n);
return array;
}
所以我测试了它
char ca[3] = {'a', 'b', 'c'};
struct array_t *array_ptr = create(5, ca);
它编译得很好(不幸的是)。据我所知6.7.6.2(p5):
如果大小是一个不是整数常量的表达式 表达式:如果它出现在函数原型范围的声明中, 它被视为被 * 替换;否则,每次都是 评估它应该有一个大于零的值。
显然n 不是一个常量表达式,const char data[n] 被简单地视为const char*,这不是我想要的。
如果这样的数组声明没有提供任何类型安全性,还有什么理由吗?也许我们可以编写一些宏函数来执行以下操作:
#define create_array_t //...
const char a1[5];
const char a2[10];
const char *a_ptr;
create_array_t(5, a1); //fine
create_array_t(5, a2); //error
create_array_t(5, a_ptr); //error
【问题讨论】:
-
只是为了好奇,您是指可变长度数组还是灵活数组成员?
-
@StephanLechner 抱歉,措辞不好。肯定是灵活的数组成员。
-
注意:说
create(5, ca);,其中ca是char [3],你不是违约吗? -
旁注,您不需要
data_offset的(容易出错的)业务。sizeof(array_t)给出了正确的结果,FAM 和所有的对齐。 -
... 您仍然需要为 FAM 分配。 sizeof 替换
data_offset