"argv[0] = name-of-executable" 是一个被接受的标准还是只是一种常见的约定?

8 浏览
0 Comments

"argv[0] = name-of-executable" 是一个被接受的标准还是只是一种常见的约定?

在C或C++应用程序中,当将参数传递给main()函数时,argv[0]是否总是代表可执行文件的名称?还是这只是一种常见的约定,不绝对保证100%正确?

0
0 Comments

根据C++标准,第3.6.1节:

argv[0]应该是指向表示用于调用程序的名称的NTMBS的初始字符的指针,或者是""

所以,至少按照标准来说,不是保证的。

我猜是以null结尾的多字节字符串?

0
0 Comments

在*nix类型的系统中,使用exec*()调用时,argv[0]将是调用者在exec*()调用中放置在argv0位置的内容。shell使用这个约定来表示程序名,大多数其他程序也遵循同样的约定,所以argv[0]通常是程序名。

但是,一个不受限制的Unix程序可以调用exec()并将argv[0]设置为任何它想要的值,所以无论C标准怎么说,你不能百分之百地依赖这个。

这个回答比paxdiablo在上面的回答更好。标准只是称之为"程序名",但是在我所知道的地方没有强制执行。Unix内核一致地将传递给execve()的字符串原封不动地传递给子进程。

C标准在它能够说的范围内是有限制的,因为它不知道'execve()'等函数。POSIX标准(opengroup.org/onlinepubs/9699919799/functions/execve.html)有更多的说法,明确指出argv[0]中的内容取决于执行'execve()'(或相关)系统调用的进程。

你可以有自己的观点,但是你关于强制执行的说法是错误的。如果一个实现不遵循标准,那么它是不符合标准的。事实上,由于"程序名"是实现定义的,像UNIX这样的操作系统只要指定了名字,就是符合标准的。这包括通过在exec系列调用中加载任何你想要的内容来明显伪造程序名。

这就是标准中使用"表示"这个词时的优势,当它引用argv[0]("它表示程序名")和argv[1..N]("它们表示程序参数")。"unladen swallow"是一个有效的程序名。

不仅是不受限制的Unix程序这样做,例如sendmail也会更改argv[0]来传达其状态:askubuntu.com/questions/868742

0
0 Comments

原因:该问题的出现是因为对于argv[0]的值是程序名还是可执行文件名存在疑问和不确定性。

解决方法:需要查阅ISO C11标准文档以获取确切的答案。根据ISO C11标准,如果argc的值大于零,那么argv[0]指向的字符串表示程序名;如果主机环境中无法获得程序名,argv[0][0]将是空字符。因此,argv[0]只是程序名的一种表示,并不一定就是程序名本身。ISO C11标准还规定,如果argc的值大于零,那么数组成员argv[0]到argv[argc-1]将包含指向字符串的指针,这些指针在程序启动之前由主机环境赋予实现定义的值。

这意味着如果主机环境不提供程序名,那么程序名可能为空;如果主机环境提供程序名,那么程序名可以是任何其他值,只要这些值能够表示程序名。然而,根据ISO标准,实现定义具有特定的含义,即实现必须记录其工作原理。即使是UNIX,在使用exec系列调用时也必须(而且确实)记录如何处理argv[0]。

因此,虽然ISO C11标准规定了argv[0]表示程序名,但并没有明确定义程序名的含义,特别是并不一定是可执行文件名。实现可以自由决定argv[0]的值,包括允许其中存储的内容不是实际的程序名。在实际编程中,不能指望argv[0]的值是可靠的。

0