函数的数组参数(例如“ char s [static 10]”)中的static关键字的目的是什么?


144

浏览一些源代码时,我遇到了一个类似这样的函数:

void someFunction(char someArray[static 100])
{
    // do something cool here
}

经过一些实验,似乎也可能出现其他限定词:

void someFunction(char someArray[const])
{
    // do something cool here
}

似乎仅[ ]在将数组声明为函数的参数时才允许使用限定符。这些是做什么的?为什么功能参数不同?

Answers:


127

第一个声明告诉编译器someArray至少 100个元素长。这可以用于优化。例如,这也意味着someArray永不NULL

请注意,C标准不要求编译器诊断对函数的调用何时不满足这些要求(即,它是静默的未定义行为)。

第二个声明只是声明someArray(不是someArray元素!)为const,即您不能编写someArray=someOtherArray。与参数相同char * const someArray

此语法仅[]在函数参数列表中的数组声明符的最内部可用。在其他情况下,这是没有意义的。

在C11 6.7.6.3/7中涵盖了以上两种情况的标准文本(在C99中为6.7.5.3/7):

参数声明为“类型数组”应调整为“类型的合格指针”,其中类型限定符(如果有的话)是在[]数组类型派生中指定的类型限定符。如果关键字static也出现在[]的数组类型推导中,则对于函数的每次调用,相应的实际参数的值应提供对数组第一个元素的访问,该元素的数量至少与大小表达式。


35
关于这个主题:我想知道是否应该考虑使用它int foo(struct bar [static 1]);而不是int foo(struct bar *);作为不接受NULL指针的函数的签名。(我知道gcc具有替代的非标准语法来标记此类功能,以便编译器可以发出警告。)
R .. GitHub停止帮助ICE 2010年

2
我刚刚检查了gcc和clang,当我要求它们与0进行比较时,都没有假定someArray总是非null。而且,我也很难在C99中找到定义它的确切子句。6.7.5.3-21中有一条注释,其中提到了预期的含义,仅此而已。我怀疑我们能否依靠这一点。此外,所有这些都不是函数签名的一部分,因此我们没有通过它强制执行任何操作。
Nordic Mainframe

5
该链接似乎已经消失了,这是它所指向的吗?pic.dhe.ibm.com/infocenter/zos/v1r12/...
罗斯艾肯

13
@NordicMainframe:已经有一段时间了,但是clang当您尝试使用[static 1]参数声明将已知NULL参数传递给函数时,现在的当前版本会正确警告。
dreamlax

1
@CiroSantilli巴拿马文件六四事件法轮功if (!someArray) { somecode... }可以删除
MM
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.