处理等于 0 的参数

Handle argc equal to 0

本文关键字:参数 处理      更新时间:2023-10-16

我最近看到了一些奇怪的东西。在 HHVM 源代码中,main()函数的前 3 行如下所示:

if (!argc) {
  return 0;
}

这有点傻,但是,我仍然忍不住想知道...为什么返回 0!?这并不是说我认为有一些正确的方法来解决这个问题,但是返回 0,通常与成功相关,似乎特别不合适。

除了不崩溃之外,是否有argc为 0 的适当响应?(甚至小于0?有关系吗?

据我所知,在 0 argc的情况下结束的唯一方法是与exec()和朋友在一起。如果由于某种原因确实发生了这种情况,那么几乎可以肯定是调用方中的错误,被调用方对此无能为力。

(标记为 C 和 C++,因为我希望两种语言的答案相同)

编辑:为了使这个问题不那么模糊和哲学,我将提供另一种选择。

if (!argc) {
  puts("Error: argc == 0");
  return 1;
}

关键点是有错误的指示并返回非零值。这是极不可能需要的,但如果是这样,您也可以尝试指出错误。另一方面,如果检测到的错误严重到argc等于 0,也许尝试访问 stdout 或 C 标准库是不好的。

请注意,C11 标准明确允许argc == 0

5.1.2.2.1 程序启动

¶1 程序启动时调用的函数名为main。实现声明否 此函数的原型。它应定义为返回类型int,并且没有 参数:

int main(void) { /* ... */ }

或带有两个参数(此处称为 argcargv ,尽管任何名称都可以是 使用,因为它们是声明它们的函数的本地):

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 的值为 大于 1,由 argv[1]argv[argc-1] 指向的字符串 表示程序参数
  • 参数
  • argcargv 以及 argv 数组指向的字符串应 可由程序修改,并在程序之间保留其最后存储的值 启动和程序终止。

10)因此,int可以用定义为int的typedef名称替换,或者argv的类型可以写成 char ** argv,等等。

"如果argc的值大于零"的两个要点显然允许argc == 0,尽管这种情况是不寻常的。

因此,从理论上讲,程序可以采取预防措施,尽管即使argc == 0 argv[0] == 0,所以只要代码不取消引用空指针,它应该没问题。 许多程序,甚至大多数程序,都没有采取这种预防措施;他们假设argv[0]不会是空指针。

我认为这只是防御性编程的一个案例,因为 HHVM 的 sorce 代码(文件 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] == NULLstrlen(argv[0])将导致分段错误。

我不熟悉 HHVM,但他们可以假设某个程序可以在没有参数(甚至没有程序名称)的情况下调用该程序。