这个问题与“数组参数 VLA 是否一致?”非常相似,唯一的区别是这里我在数组声明的
static
和 [
中使用了 ]
关键字(在C11),这意味着声明的数组应该至少有 len
个元素的空间。这是一个例子:
#include <stddef.h>
#include <stdio.h>
void print_array(size_t len, const int arr[static len]) {
for (size_t i = 0; i < len; i++) {
printf("%d\n", arr[i]);
}
}
int main(void) {
const int arr[] = {1, 2, 3, 4};
print_array(sizeof arr / sizeof *arr, arr);
return 0;
}
在 GCC 和 Clang 上使用
-Wvla
标志编译此代码时,会发出以下警告:
main.c:4:1: warning: ISO C90 forbids variable length array ‘arr’ [-Wvla]
4 | void print_array(size_t len, const int arr[static len]) {
| ^~~~
即使指定
arr
,static
作为 VLA 又有什么意义呢?这难道不会使得 static
对于这样的情况毫无用处吗?
我尝试在C11标准中寻找答案,但找不到。
谢谢!
GCC 关于这是 VLA 的说法正确吗?
C 2018(和 C 2011)6.7.6.2 4 说,数组声明符:
...如果大小是整数常量表达式,并且元素类型具有已知的常量大小,则该数组类型不是变长数组类型;否则,数组类型是变长数组类型。
声明
const int arr[static len]
中,len
不是整型常量表达式,因此数组类型是变长数组类型。所以 GCC 是正确的。
即使指定静态,
作为 VLA 有什么意义?arr
6.7.6.3 7 说:
...如果关键字
也出现在数组类型派生的static
和[
中,则对于每次调用该函数,相应实参的值应提供对数组第一个元素的访问至少具有大小表达式指定的元素数量。]
编译器如何使用此功能的一个示例是,如果函数体包含计算表达式
arr[i]
,其中 arr
已用 const int array[static len]
声明,则编译器可能会假定 i
< len
,并且可以在此基础上进行优化。
这不会让
对于这样的情况毫无用处吗?static
不,尽管如果编译器不利用此信息,我也不会感到惊讶。