C99中数组参数用[static 0]时传NULL是否符合标准?
关于C99中
[static len]参数与foo(0, NULL)调用的合规性问题 void foo(size_t len, int array[static len]) { } int main(int argc, char *argv[]) { foo(0, NULL); return 0; }
函数foo的第二个参数采用C99的[static len]语法,该语法向编译器保证传入的指针指向至少len个元素。现正式问询:调用foo(0, NULL)是否严格符合C99标准?
现有分析
C99标准的**§6.7.5.3 p7**条款相关内容如下:
参数声明为“数组类型”应调整为“限定指针类型”,其中类型限定符(若有)是数组类型推导中
[和]内指定的限定符。若static关键字也出现在数组类型推导的[和]内,则函数每次调用时,对应实参的值应能提供对一个数组首元素的访问,该数组的元素数量至少不小于大小表达式指定的数量。
注意标准并未明确说明“实参必须非空”,非空要求仅为隐含:根据定义,NULL指针无法提供对任何对象首元素的访问,但C99中无直接语句规定非空要求。
当len == 0时,此区别至关重要:大小表达式求值为0时,标准要求实参能提供对一个至少0个元素的数组首元素的访问,这是一个虚真满足的约束——无需访问任何元素,因此NULL未违反“提供访问”的要求。
使用Clang或GCC编译时会输出如下警告:
Compiler stderr <source>:9:5: warning: null passed to a callee that requires a non-null argument [-Wnonnull] 9 | foo(0, NULL); | ^ ~~~~ <source>:3:26: note: callee declares array parameter as static here 3 | void foo(size_t len, int array[static len]) | ^ ~~~~~~~~~~~~ 1 warning generated. Program returned: 0
具体问题
- C99标准是否定义了
[static 0]的行为?还是零长度static数组参数本身已属于未定义/未指定行为? - 若
static N约束在N == 0时虚真满足,是否意味着foo(0, NULL)是完全定义的行为? - 使用基于VLA的边界(即
len为运行时变量且值为0的[static len])与编译时常量[static 0]相比,是否会改变分析结论?
内容的提问来源于stack exchange,提问作者Parminder Singh
相关产品推荐
相关产品推荐

