我最近看到一些好奇的东西。在HHVM源代码中,main()
函数的前3行如下所示:
if (!argc) {
return 0;
}
这有点傻,但是,我仍然无法帮助想知道...... 为什么要回归0?这不是我认为的那样&#39 ; s一些正确的方法来处理这个问题,但返回0,通常与成功相关,似乎特别不合适。
除了没有崩溃之外,曾经是否有argc
对0的适当回应? (甚至还不到0?)这有关系吗?
我知道的最后一个argc
为0的情况的唯一方法是exec()
和朋友。如果出于某种原因确实发生了这种情况,那几乎肯定是调用者中的一个错误,被调用者无法做很多事情。
(标记为C和C ++,因为我希望两种语言的答案相同)
编辑:为了让问题不那么模糊和哲学,我会提供另一种选择。
if (!argc) {
puts("Error: argc == 0");
return 1;
}
关键点在于指示错误并返回非零值。这种情况极不可能需要,但如果是这样,你可能会尝试指出错误。另一方面,如果检测到的错误与argc
等于0一样严重,那么尝试访问stdout或C标准库可能是不好的。
答案 0 :(得分:7)
请注意,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
可以替换为定义为int
的typedef名称,或者argv
的类型可以写为char ** argv
,等等。
“如果argc
的值大于零”的两个要点明确允许argc == 0
,尽管这种情况不太常见。
因此,从理论上讲,程序可以采取预防措施,尽管argv[0] == 0
即使argc == 0
,所以只要代码不取消引用空指针,它应该没问题。许多计划,甚至大多数计划,都没有采取这些预防措施;他们假设argv[0]
不是空指针。
答案 1 :(得分:4)
由于Defensive programming的代码中的以下代码段(文件 hphp / hhvm / main.cpp),我认为这只是HHVM的一个案例):
int main(int argc, char** argv) {
if (!argc) {
return 0;
}
HPHP::checkBuild();
int len = strlen(argv[0]);
在行中:
int len = strlen(argv[0]);
if argc == 0
- > argv[0] == NULL
和strlen(argv[0])
会导致细分错误。
我不熟悉HHVM,但他们可以假设某些程序可以在没有参数的情况下调用程序(甚至不是程序名称)。