根据我的理解,每个VLA都有一个隐藏的变量,它的大小可以被获得'由sizeof
运营商提供。我不能到达的是指向功能参数中使用的VLA的指针 - 为什么它们的大小不会被自动推导并存储在这个隐藏变量中 - 为什么我们应该明确地提供它。在这种情况下,为什么我们应该使用它,因为我们已经有了指向未知大小数组的类型'?
我的意思是:
void func(size_t, int (*)[*]); //function accepting pointer to VLA
void func_1(size_t, int (*)[]); //function accepting pointer to array of unknown bound
void func(size_t sz, int (*parr)[sz]) //implementation of 'func'
{
printf("%lu", sizeof(*parr) / sizeof(int));
printf("%lu", sz);
}
void func_1(size_t sz, int(*parr)[]) //implementation of 'func_1'
{
//printf("%lu", sizeof(*parr) / sizeof(int)); //error: invalid application of 'sizeof' to an incomplete type 'int []'
printf("%lu", sz);
}
我可以看到使用' func'而不是' func_1'就是' sizeof'运营商将返回' sz'。
的初始值的副本上述功能的示例用法:
int main()
{
size_t sz = 3;
int arr[sz];
func(sizeof(arr) / sizeof(int), &arr);
func_1(sizeof(arr) / sizeof(int), &arr);
return 0;
}
为什么无法隐式指定指向VLA参数的指针大小?这至少可以很好地利用语法:
void func(int (*parr)[*]) // size copied from function argument
{
printf("%lu", sizeof(*parr) / sizeof(int));
printf("%lu", sz);
}
然后调用这个函数:
int main()
{
size_t sz = 3;
int arr[sz];
func(&arr);
return 0;
}
将导致数组隐藏的大小变量值为' 3'作为隐藏的参数传递给' func'创建类似于实例化以前的功能的代码' func'使用当前语法并使用' sizeof'运算符传递数组。
如果您有足够的好奇心将所提出的语法编译成任何Clang编译器 - 您将获得一个复活节彩蛋(;。
答案 0 :(得分:1)
可变长度数组的长度仅在本地已知(因为它必须是堆栈分配存储并提供sizeof
语义)。当它传递给函数时,它只是一个常规数组类型,因此必须明确传递大小。
答案 1 :(得分:1)
可变长度数组(VLA)的大小与类型相关联,而不是与对象相关联。
例如,给定:
size_t n = 41;
int vla[n+1];
printf("sizeof vla = %zu\n", sizeof vla);
编译器创建一个初始化为n+1
的匿名对象,我将其称为_anon
,并定义类型int[_anon]
,它是数组对象{{1}的类型}。 (请注意,稍后更改vla
的值不会更改n
的值或VLA类型的大小。)
你也可以写:
_anon
将size_t n = 41;
typedef int vla_t[n+1];
vla_t vla;
应用于表达式(在本例中,恰好是对象名称)会产生该表达式类型的大小。
在sizeof
内,func
的类型不可见,因此无法获得其大小。 vla
是指向未指定大小的parr
数组的指针。类型int
(未指定大小的数组)和int[]
(长度为int[n+1]
的可变长度数组)`兼容,但类型不同
答案 2 :(得分:0)
在几十年前应该废除的令人讨厌的可怕的kludge,但现在已经被太多的代码所依赖,C编译器认为数组类型的所有函数参数都等同于指针的参数 - 元素类型,是否指定了数组大小。
定义一个函数可能没有任何重大的技术困难,通过该语法可以传递任意大小的数组并自动知道它们有多大。不幸的是:
目前将数组传递给函数意味着将指针传递给第一个元素;添加一个新语法,这意味着其他东西会产生比它解决更多的混乱。
如果现有代码接收指针和整数,并将该指针视为标识指定长度数组的第一个元素,则传递"数组"一种期望一种新型"数组可能很棘手。
可以通过添加语法将指针/长度组合转换为"已知大小的数组来解决第二个问题。可以传递给接受这些东西的方法。然而,前一个问题可能是无法解决的,除非或直到C被一种不专注于指针的语言所取代,并且#34;优化"它们甚至不再相关。