我最近看到一些好奇的东西。在HHVM源代码中,前3行 main()
功能如下:
if (!argc) {
return 0;
}
这有点傻,但是,我还是忍不住想知道...... 为什么返回0!? 并不是我认为有一些正确的方法可以解决这个问题,但通常与成功相关的0返回似乎特别不合适。
除了不崩溃,还有 曾经 一个适当的回应的情况 argc
是0? (甚至还不到0?)这有关系吗?
我知道的最后一个案例就是结束 argc
0是与 exec()
和朋友。如果出于某种原因确实发生了这种情况,那几乎可以肯定是调用者中的一个错误,被调用者无法做太多事情。
(标记为C和C ++,因为我希望两种语言的答案相同)
编辑: 为了使问题不那么模糊和哲学,我会提供另一种选择。
if (!argc) {
puts("Error: argc == 0");
return 1;
}
关键点是指示错误并返回非零值。这种情况极不可能需要,但如果是这样,你可能会尝试指出错误。另一方面,如果检测到的错误与严重一样严重 argc
等于0,也许有理由尝试访问stdout或C标准库是不好的。
我认为这只是一个例子 防守编程 由于下面的代码片段 HHVM的代码(文件 HPHP / HHVM / main.cpp中):
int main(int argc, char** argv) {
if (!argc) {
return 0;
}
HPHP::checkBuild();
int len = strlen(argv[0]);
在线:
int len = strlen(argv[0]);
如果 argc == 0
- > argv[0] == NULL
和 strlen(argv[0])
会导致分段错误。
我不熟悉 HHVM 但是他们可以假设一些程序可以在没有参数的情况下调用程序(甚至不是程序名)。
请注意,C11标准明确允许 argc == 0
:
5.1.2.2.1程序启动
¶1程序启动时调用的函数被命名 main
。实施宣布否
这个功能的原型。它应定义为返回类型 int
没有
参数:
int main(void) { /* ... */ }
或者有两个参数(这里称为 argc
和 argv
,虽然任何名字都可能
使用,因为它们是声明它们的函数的本地):
int main(int argc, char *argv[]) { /* ... */ }
或同等学历;10) 或者以其他一些实现定义的方式。
¶2如果它们被声明,则参数为 main
功能应遵守以下规定
限制:
- argc的值应为非负值。
argv[argc]
应该是一个空指针。
- 如果值
argc
大于零的数组成员 argv[0]
通过
argv[argc-1]
包含应包含指向字符串的指针
程序启动前主机环境实现定义的值。该
意图是在程序启动之前为程序提供信息
来自托管环境中的其他地方。如果主机环境不具备
为字符串提供大写和小写的字母,实现
应确保以小写字母收到字符串。
- 如果值
argc
大于零,字符串指向 argv[0]
代表着 程序名称; argv[0][0]
如果是,则应为空字符
程序名称不能从主机环境中获得。如果值 argc
是
大于一,指向的字符串 argv[1]
通过 argv[argc-1]
代表 程序参数。
- 参数
argc
和 argv
和指向的字符串 argv
阵列应
可以由程序修改,并在程序之间保留它们最后存储的值
启动和程序终止。
10) 从而, int
可以用定义为的typedef名称替换 int
,或者类型 argv
可写成
char ** argv
, 等等。
这两个要点是'如果有价值的话 argc
'大于零''明确允许 argc == 0
虽然这种情况很不寻常。
因此,从理论上讲,一个程序可以采取预防措施 argv[0] == 0
即使 argc == 0
,所以只要代码不取消引用空指针,它应该没问题。许多计划,甚至大多数计划,都没有采取这些预防措施;他们认为 argv[0]
不会是空指针。