一个非常简单的C程序:
#include <stdio.h>
#include <stdlib.h>
void process(int array[static 5]){
int i;
for(i=0; i<5; i++)
printf("%d ", array[i]);
printf("\n");
}
int main(){
process((int[]){1,2,3});
process(NULL);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我编译它: gcc -std=c99 -Wall -o demo demo.c
它确实编译,当我运行它时,它崩溃(非常可预测).
为什么?static数组参数中关键字的用途是什么(这个构造的名称是什么btw?)?
优化器static有一个指示(一个提示 - 但不超过一个提示)它可能假设数组中有一个最小的适当数字(在例子中为5)元素(因此数组指针是也不是空的).它也是程序员使用函数的指令,它必须将足够大的数组传递给函数以避免未定义的行为.
ISO/IEC 9899:2011
§6.7.6.2数组声明符
约束
1除了可选的类型限定符和关键字之外static,[和]可以分隔表达式或*.如果它们分隔表达式(指定数组的大小),则表达式应具有整数类型.如果表达式是常量表达式,则其值应大于零.元素类型不应是不完整或函数类型.可选的类型限定符和关键字static只出现在具有数组类型的函数参数的声明中,然后仅出现在最外层的数组类型派生中.§6.7.6.3函数声明符(包括原型)
7的参数为"类型的阵列"的声明,应调整为"合格指针输入",其中类型限定符(如果有的话)的那些内的指定
[和]该阵列类型的推导.如果关键字static也出现在数组类型派生的[和]中,那么对于每次对函数的调用,相应的实际参数的值应该提供对数组的第一个元素的访问,其中至少有与该大小指定的元素一样多的元素.表达.
您的代码崩溃,因为如果您将空指针传递给期望数组的函数(保证是5个元素的数组的开头),您将调用未定义的行为,崩溃是处理您的错误的一种非常明智的方法.
将3个整数的数组传递给保证5个整数数组的函数时,它会更加微妙; 再次,您调用未定义的行为,结果是不可预测的.崩溃的可能性相对较小; 虚假结果非常可能.
实际上,static在此上下文中有两个单独的作业 - 它定义了两个单独的合同:
如果该函数的用户违反了该函数的要求,那么所有地狱都可能会崩溃('鼻子恶魔'等;通常是未定义的行为).