【发布时间】:2019-01-10 22:10:54
【问题描述】:
根据Arrays of Variable Length 上的 GNU 文档,可以使用 sizeof 运算符来确定传递给函数的可变长度数组的大小:
您还可以使用可变长度数组作为函数的参数:
struct entry tester (int len, char data[len][len]) { /* … */ }数组的长度在分配存储时计算一次,并记住数组的范围,以防您使用
sizeof访问它。
但是,当使用下面的完整代码示例尝试此示例时,sizeof 运算符返回指针的大小,不是分配的 vla 的大小,正如基于 GNU 的预期上面的sn-p。
我知道在 C 中传递数组类似于传递指向数组第一个元素的指针,但是由于我们在这种情况下在函数签名中指定了大小,所以我希望在使用 @ 时会模仿这种行为987654325@在声明数组的范围内。
我也意识到我可以使用len 参数来计算大小;但为了方便和理解 GNU 实现,我仍然认为这是一个有趣(如果不重要)的问题。
提前感谢任何可以提供见解的人!
// file: vla.c
#include <stdio.h>
void foo(int len, char data[len][len]) {
printf("sizeof \"foo\" data: %lu\n", sizeof(data));
}
int main(int argc, char * argv[]) {
char data[argc][argc];
printf("sizeof \"main\" data: %lu\n", sizeof(data));
foo(argc, data);
}
编译使用:
gcc vla.c -o vla -std=c11
调用使用:
./vla 2 3 4 5
输出:
sizeof "main" data: 25
sizeof "foo" data: 8
分析:
maindata 的大小有意义; argc 是 5,因此它是一个 (5 * 5 = 25) 字节的二维数组。
foodata 的大小预计也是 25,但实际上是指针的大小。似乎编译器没有使用它知道data 在foo 中的大小这一事实,因为它是函数签名的一部分。
【问题讨论】:
-
我怀疑你会发现正常的规则适用于函数参数(你得到一个指针的大小)。您引用的文本主要指的是在函数内部定义的数组(您不能在全局范围内定义可变大小的数组)。话虽如此,手册参考肯定意味着您正在做的事情应该有效。
-
旁白:最好将
"%zu"与size_t一起使用-->printf("%zu\n", sizeof(...)); -
经过一番疯狂的思考,我认为调用函数时没有分配存储空间。我认为示例代码之后的段落是不合理的。但从手册上看并不明显。
-
@JonathanLeffler,我同意这个评估。也感谢您的格式修复,非常感谢!
标签: c arrays gcc sizeof variable-length-array