我通常将主函数的形式参数声明为 或int argc, char* argv[]
,int argc, char** argv
以便从命令行获取实际参数。但我注意到一位资深 C 程序员(他恰好也是 ISO 委员会成员和 C23 修订版的合著者)使用了int argc, char* argv[argc+1]
或int argc, char* argv[argc]
。这样做有什么意义?
我通常将主函数的形式参数声明为 或int argc, char* argv[]
,int argc, char** argv
以便从命令行获取实际参数。但我注意到一位资深 C 程序员(他恰好也是 ISO 委员会成员和 C23 修订版的合著者)使用了int argc, char* argv[argc+1]
或int argc, char* argv[argc]
。这样做有什么意义?
以下参数声明是等效的:
int argc, char* argv[argc]
int argc, char* argv[argc+1]
int argc, char* argv[]
int argc, char** argv
这种等价性在C 标准的第 6.7.6.3p7 节中有详细说明:
根据上文,前三种情况被调整为与第四种情况等同。由于
static
其中任何一种情况都没有限定词,因此不属于任何例外。开发人员可能将此作为一种内部文档的形式来说明这些数组的大小。
对于人员和静态代码分析器来说,
char* argv[argc+1]
正确指出了索引arg[]
可以被访问(例如读取指针)[0...argvc]
。注意:
argv[argc]
预计为NULL
。C99、C23 以及可选的 C11、C17,将 4 视为等效的。
C11 ISO/IEC 9899:2011 第 6.7.6.2 款第 1 段规定
作为函数参数的数组声明为编译器提供了有关参数之间关系的信息,具体来说,哪个参数指定了传递的数组可以被索引的有效长度。
这可以用于静态分析,或者在调试版本中自动生成参数验证代码,或者在稳健性和防御性执行很重要的情况下使用。