gpt4 book ai didi

c - 具有副作用的可变长度数组参数大小表达式

转载 作者:行者123 更新时间:2023-12-04 11:10:09 26 4
gpt4 key购买 nike

这个问题源于Eric Postpischil在in another thread.中所作的评论。

我很难理解将可变长度数组(VLA)用作函数参数:


不检查数组大小。
无法从数组中恢复数组大小,因为标准类型调整数组->指针也适用于VLA,如下面的sizeof()调用所示。即使完全有可能在堆栈上传递整个数组,就像在定义VLA时在堆栈上创建VLA一样。
大小必须与指针一样作为附加参数传递。


那么,如果该语言没有提供任何优势并且像指针的任何其他数组参数一样进行调整,为什么该语言允许使用VLA参数声明函数呢?如果语言未使用大小表达式(例如,检查实际参数的大小)并且在函数内部无法获得大小表达式(仍然需要为此传递一个显式变量),为什么要对其进行评估?

为了使我更困惑,请考虑以下程序(实时示例here)。所有函数声明显然都是等效的。但是,正如Eric在另一个线程中指出的那样,函数声明中的参数大小表达式是在运行时求值的。大小表达式不会被忽略。

我不清楚这会带来什么好处,因为大小及其评估没有影响(可能的副作用除外)。特别是要重复一遍,该信息不能被函数内部的代码使用。最明显的变化是将VLA传递给类似结构的堆栈。毕竟,它们通常也位于调用方的堆栈中。但是,就像使用恒定长度的数组一样,在声明时已经将类型调整为指针-以下所有声明都是等效的。尽管如此,仍会评估无用和废弃的数组大小表达式。

#include <stdio.h>

// Nothing to see here.
extern void ptr(int *arr);

// Identical to the above.
extern void ptr(int arr[]);

// Still identical. Is 1 evaluated? Who knows ;-).
extern void ptr(int arr[1]);

// Is printf evaluated when called? Yes.
// But the array is still adjusted to a pointer.
void ptr(int arr[printf("Call-time evaluation of size parameter\n")]){}

// This would not compile, so the declarations above must be equivalent.
// extern void ptr(int **p);

int main()
{
ptr(0);
ptr(0);

return 0;
}

最佳答案

...可以省略size变量和...在运行时将要评估的大小...;但是有什么用呢?


顶级大小信息丢失😢,在array参数中现在是一个指针参数。然而,有了2D VLA函数参数,这些参数变成了指向1D数组的指针,代码就知道了该数组的维数。

void g(size_t size, size_t size2, int arr[size][size2]) {
printf("g: %zu\n", sizeof(arr));
printf("g: %zu\n", sizeof(arr[0]));
}

int main(void) {
int arr[10][7];
g(10, 7, arr);
}


输出量

g: 8   pointer size
g: 28 7 * int size




或者,将指针传递给数组。

void g2(size_t size, size_t size2, int (*arr)[size][size2]) {
printf("g2: %zu\n", sizeof(arr));
printf("g2: %zu\n", sizeof(*arr));
}

int main(void) {
int arr[10][7];
g2(10, 7, &arr);
}


输出量

g2: 8    pointer size
g2: 280 10 * 7 * int size

关于c - 具有副作用的可变长度数组参数大小表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54380305/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com