处理 argc 等于 0

Handle argc equal to 0

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

if (!argc) {
  return 0;
}

有点傻,但是,我还是忍不住想知道... 为什么 return 0!? 并不是我认为有一些正确的处理此问题的方法,但通常与成功相关的 returning 0 似乎特别不合适。

除了不崩溃,有没有 曾经argc 为 0 的适当响应的情况? (甚至小于 0?)这重要吗?

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

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

编辑: 为了尽量使问题不那么模糊和哲学化,我将提供一个替代方案。

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

关键点是有错误指示并且 returned 是一个非零值。这极不可能需要,但如果需要,您不妨尝试指出错误。另一方面,如果检测到的错误严重到 argc 等于 0,那么尝试访问 stdout 或 C 标准库可能是有原因的。

我认为这只是Defensive programming due to the following snippet in the 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]);

if argc == 0 -> argv[0] == NULLstrlen(argv[0]) 将导致段错误。

我不熟悉 HHVM 但他们可以假设某些程序可以不带参数调用程序(甚至不是程序名称)。

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

5.1.2.2.1 Program startup

¶1 The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of int and with no parameters:

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

or with two parameters (referred to here as argc and argv, though any names may be used, as they are local to the function in which they are declared):

int main(int argc, char *argv[]) { /* ... */ }

or equivalent;10) or in some other implementation-defined manner.

¶2 If they are declared, the parameters to the main function shall obey the following constraints:

  • The value of argc shall be nonnegative.
  • argv[argc] shall be a null pointer.
  • If the value of argc is greater than zero, the array members argv[0] through argv[argc-1] inclusive shall contain pointers to strings, which are given implementation-defined values by the host environment prior to program startup. The intent is to supply to the program information determined prior to program startup from elsewhere in the hosted environment. If the host environment is not capable of supplying strings with letters in both uppercase and lowercase, the implementation shall ensure that the strings are received in lowercase.
  • If the value of argc is greater than zero, the string pointed to by argv[0] represents the program name; argv[0][0] shall be the null character if the program name is not available from the host environment. If the value of argc is greater than one, the strings pointed to by argv[1] through argv[argc-1] represent the program parameters.
  • The parameters argc and argv and the strings pointed to by the argv array shall be modifiable by the program, and retain their last-stored values between program startup and program termination.

10) Thus, int can be replaced by a typedef name defined as int, or the type of argv can be written as char ** argv, and so on.

两个要点说 'if the value of argc is greater than zero' 显然允许 argc == 0,尽管这种情况并不常见。

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