GCC 关于将其作为 VLA 的说法正确吗?

Tac*_*chi 3 c c99 language-lawyer

这个问题与“ Are conformant arrayparameters VLAs? ”非常相似,唯一的区别是这里我在数组声明的andstatic中使用关键字(C99 中引入),这意味着声明的数组应该有空间至少对于元素。这是一个例子:[]len

\n
#include <stddef.h>\n#include <stdio.h>\n\nvoid print_array(size_t len, const int arr[static len]) {\n    for (size_t i = 0; i < len; i++) {\n        printf("%d\\n", arr[i]);\n    }\n}\n\nint main(void) {\n    const int arr[] = {1, 2, 3, 4};\n    print_array(sizeof arr / sizeof *arr, arr);\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

当在 GCC 和 Clang 上使用该-Wvla标志编译此代码时,会发出以下警告:

\n
main.c:4:1: warning: ISO C90 forbids variable length array \xe2\x80\x98arr\xe2\x80\x99 [-Wvla]\n    4 | void print_array(size_t len, const int arr[static len]) {\n      | ^~~~\n
Run Code Online (Sandbox Code Playgroud)\n

arr即使指定了,成为 VLA又有什么意义呢staticstatic对于这样的情况,这不是毫无用处吗?

\n

我尝试在 C 标准中寻找答案,但找不到。

\n

谢谢!

\n

Eri*_*hil 6

\n

GCC 关于将其作为 VLA 的说法正确吗?

\n
\n

C 2018(和 C 2011)6.7.6.2 4 说,数组声明符:

\n
\n

\xe2\x80\xa6 如果大小是整数常量表达式并且元素类型具有已知的常量大小,则该数组类型不是变长数组类型;否则,数组类型是变长数组类型。

\n
\n

声明中const int arr[static len],len不是整型常量表达式,因此数组类型是变长数组类型。所以GCC是正确的。

\n
\n

arr即使指定静态,作为 VLA又有什么意义呢?

\n
\n

6.7.6.3 7 说:

\n
\n

\xe2\x80\xa6 如果关键字static也出现在数组类型派生的[and]中,则对于每次调用该函数,相应实参的值应提供对数组第一个元素的访问,其数量至少与由大小表达式指定的元素。

\n
\n

编译器如何使用此功能的一个示例是,如果函数体包含已用 声明的求值表达式,arr[i]则编译器可能会假定< ,并且可以基于此进行优化。arrconst int array[static len]ilen

\n
\n

static对于这样的情况,这不是毫无用处吗?

\n
\n

不,尽管如果编译器不利用这些信息,我也不会感到惊讶。

\n