我看到了一些复杂的函数定义。
void foo(double A[static 10]) {
double B[10];
}
是否有效C& C ++代码?它是C99或C ++标准引入的新语法吗?它的目的是什么?我应该什么时候使用它?有什么需要呢?
答案 0 :(得分:4)
此C99表示法void foo(double A[static 10])
表示该函数可以假定A
指向10个有效参数(从*A
到A[9]
)。该表示法使程序更具信息性,帮助编译器优化为函数foo
生成的代码,并检查它是否在每个调用站点正确调用。
在引入符号的C99标准中,条款6.7.5.2和6.7.5.3:7涵盖了这一点。
“...如果关键字static也出现在数组类型派生的[和]中,那么对于每次对函数的调用,相应的实际参数的值应至少提供对数组的第一个元素的访问大小表达式“
指定的元素数量
一个常见的用途是f(int p[static 1])
,它或多或少等同于其他语言中 reference (与指针相对)的概念。如果声明了这样的函数并且在调用站点传递了一个空指针,Clang会发出警告(因为符号明确表示p
不是NULL
)。但是,我最后一次尝试时,Clang没有警告f(&a + 1)
,这是一个耻辱(但编译器不必发出所有警告。发出一些警告是好的的话):
#include <stdio.h>
void f(int p[static 1])
{
printf("%d\n", *p);
}
int main(){
int a = 0;
f(&a + 1);
f(0);
f(&a);
}
Clang警告第二次电话,但遗憾的是不是第一次电话:
$ clang t.c t.c:11:3: warning: null passed to a callee which requires a non-null argument [-Wnonnull] f(0); ^ ~ t.c:3:12: note: callee declares array parameter as static here void f(int p[static 1]) ^~~~~~~~~~~ 1 warning generated.
语法可能看起来有点奇怪,但C99标准化委员会显然决定在不会引起歧义的地方重用预先存在的static
关键字,以避免引入新的关键字(可能会破坏现有的程序。)