Arrays 什么是“;静态”;在C中的参数数组类型中?

Arrays 什么是“;静态”;在C中的参数数组类型中?,arrays,function,parameters,static,c99,Arrays,Function,Parameters,Static,C99,我看到了下面这个复杂的函数定义 void foo(double A[static 10]) { double B[10]; } 是有效的C+C++代码吗?是C99还是C++标准引入的新语法?它的目的是什么?我应该什么时候用?这需要什么?这个C99符号,void foo(双A[static 10]),意味着函数可以假设A指向10个有效参数(从*A到A[9])。该符号使程序信息更加丰富,有助于编译器优化为函数foo生成的代码,并检查在每个调用站点是否正确调用了该函数 在引入符号的C9

我看到了下面这个复杂的函数定义

void foo(double A[static 10]) {
   double B[10];    
}

是有效的C+C++代码吗?是C99还是C++标准引入的新语法?它的目的是什么?我应该什么时候用?这需要什么?

这个C99符号,
void foo(双A[static 10])
,意味着函数可以假设
A
指向10个有效参数(从
*A
A[9]
)。该符号使程序信息更加丰富,有助于编译器优化为函数
foo
生成的代码,并检查在每个调用站点是否正确调用了该函数

在引入符号的C99标准中,第6.7.5.2条和第6.7.5.3:7条涵盖了这一点

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


一个常见的用法是
f(intp[static 1])
,它或多或少等同于其他语言中的引用(与指针相反)。如果声明了这样一个函数,并且在调用站点上传递了一个null指针,则Clang会发出警告(因为该符号明确表示
p
将不会是
null
)。但是,上次我尝试时,Clang没有为
f(&a+1)
发出警告,这是一个遗憾(但编译器不必发出所有警告。发出一些警告已经很好了):

#包括
void f(int p[静态1])
{
printf(“%d\n”,*p);
}
int main(){
int a=0;
f(a+1);
f(0);
f&a;
}
叮当声警告第二次呼叫,但不幸的是,不是第一次呼叫:

$ 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. $clang t.c t、 c:11:3:警告:传递给需要非null参数的被调用方的null [-Wnonnull] f(0); ^ ~ t、 c:3:12:注意:被调用方在这里将数组参数声明为静态 void f(int p[静态1]) ^~~~~~~~~~~ 生成1个警告。

语法可能有点奇怪,但C99标准化委员会显然决定在不引起歧义的地方重用预先存在的
static
关键字,以避免引入新关键字(这可能会破坏现有程序).

可能的副本也可能有帮助。这不是标准。而是一个叮当声的扩展。由于某种原因,
void f(int p[static 1])
的类型与
void f(int p[1])
void f(int*p)
相同!!!例如,GCC不会发出这种误导性的警告。@CIS不是很好,但也很糟糕,我觉得很奇怪,在我引用了C99标准中允许这种构造的条款之后,你竟然费心评论说。该构造的目标也是允许发出Clang的警告,因此在本例中,Clang在发出警告方面优于GCC。这在我的答案中的C99引号中显示。@CIS不是很好,但在我看来,坏的
f
g
h
不一样。GCC也可以为
f
生成更好的代码(根据我在回答中提到的C99条款),但正如我们已经说过的,它不如这个例子中的Clang。请阅读我的评论。@CIS不是很好,但很糟糕,您是说编译器没有义务发出警告。大多数警告都是这样:C标准中只有少数“约束”部分需要诊断。这句话没有回答这个问题,也没有与这个答案中所说的任何内容相矛盾。这个答案已经包含了“编译器不必发出所有警告。发出一些警告已经很好了”。我不知道你认为你声称
int p[static 1]
是非标准的,或者你在别处输入了两条很长的注释,这会给讨论增添什么内容。 $ 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.