全局使用 argv 指针安全吗?

Is it safe to use the argv pointer globally?

全局使用argv指针安全吗?还是有可能失效的情况?

即:此代码安全吗?

char **largs;
void function_1()
{
    printf("Argument 1: %s\r\n",largs[1]);
}
int main(int argc,char **argv)
{
    largs = argv;
    function_1();
    return 1;
}

只要main()函数不退出就应该是安全的。 main() 退出后可能发生的事情的一些例子是:

  1. 全局和静态变量的析构函数
  2. 线程 运行 长于 main()

存储的 argv 不能用于这些。

The reference 没有说任何可以假设 main() 函数参数的生命周期与函数参数生命周期的一般规则不同的理由。

只要argv指针本身是有效的,C/C++运行时就必须保证这个指针指向的内容是有效的(当然,除非有什么东西破坏了内存)。所以使用指针和那么长的内容一定是安全的。在 main() returns 之后,C/C++ 运行时也没有理由保持内容有效。所以上面的推理适用于指针和它指向的内容。

是的,全局使用argv是安全的;您可以像在程序中使用任何 char** 一样使用它。 C99 标准甚至指定了这一点:

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.

C++ 标准没有类似的段落,但同样是隐含的,没有相反的规则。

请注意,C++ 和 C 是不同的语言,您应该只选择一种来提出问题。

您可以将它们作为参数传递,或将它们存储在 global variables 中。只要您不从 main return 并尝试在 atexit 处理程序或全局范围内变量的析构函数中处理它们,它们仍然存在并且可以正常访问来自任何范围。

is it safe to use the argv pointer globally

这需要更多的说明。正如 C11 规范在章节 §5.1.2.2.1 中所说,程序启动

[..].. 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)

这意味着,变量本身的 范围 限于 main()。它们本身不是全球

标准又说,

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.

也就是说,这些变量的生命周期直到main()执行完毕。

因此,如果您使用全局变量来保存来自 main() 的值,您可以安全地使用这些全局变量在任何其他函数中访问相同的值。

是的,对于以太 C 或 C++ 来说是安全的,因为在 main 完成后没有线程。

comp.lang.c.moderated 新闻组上的

This thread 从 C 标准的角度详细讨论了这个问题,包括引用显示 argv 数组的内容(而不是 argv 指针本身,例如,如果你获取了一个地址 &argv 并存储了它)持续到 "program termination",并且断言 "obvious" 程序终止尚未以与此相关的方式发生,而 atexit - 注册函数正在执行:

The program has not terminated during atexit-registered function processing. We thought that was pretty obvious.

(我不确定 Douglas A. Gwyn 是谁,但听起来 "we" 是指 C 标准委员会?)

讨论的上下文主要是关于存储指针的副本argv[0](程序名称)。

相关的C标准文本是5.1.2.2.1:

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.

当然,C++ 不是 C,它的标准在这个问题上可能略有不同,或者没有解决这个问题。