这个问题建立在这个的基础上,它描述了以下内容如何等效:
int f(int a[10]) { ... } // the 10 makes no difference
int f(int a[]) { ... }
int f(int *a) { ... }
在有关函数原型范围的文档中,提供了以下示例:
int f(int n, int a[n]); // n is in scope, refers to first param
这让我质疑以下内容在多大程度上是等效的:
// 1.
int f(int n, int a[n]) { ... }
int f(int n, int *a) { ... }
// my guess: exactly equivalent
// 2.
int x = 10; int f(int a[x]) { ... }
int x = 10; int f(int *a) { ... }
// my guess: exactly equivalent
// 3.
int f(int a[n], int n) { ... }
int f(int *a, int n) { ... }
// my guess: not equivalent: first f won't compile, second will
结论性问题:
int f(int arr[n])
和int f(int *arr)
总是等价的吗?n
,即使它的值不会被使用。
n
的唯一原因是作为文档来指示数组应具有的最小长度。确保 n
在范围内并且具有正确的类型,确保此文档有意义int f(int arr[n])
和int f(int *arr)
总是等价的吗?不。 C标准在这一点上是有缺陷的;它没有说明
n
中的 int arr[n]
是否被评估。
int arr[n]
名义上声明一个可变长度数组(假设n
是某个对象的标识符,而不是常量的宏)。 C 标准规定对可变长度数组的大小进行评估,还规定参数声明 int arr[n]
自动调整为 int *arr
,但尚不清楚这些出现的顺序。 GCC 和 Clang 的不同之处这一点; Clang 计算数组大小,但 GCC 不计算。对于合格对象 n
,这没有什么区别,但是,如果 n
是易失性的,或者数组大小是其他具有副作用的表达式,那么它确实会产生影响。
n
,即使它的值不会被使用。编译器需要解析代码以确定其语法结构。如果那里有一个关键字,而不是一个标识符,编译器将不得不给你一个不同的错误消息。或者那里的关键字可以是
static
,在该位置有效。