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.