C++ “argv[0] = name-of-executable”是公认的标准还是只是一个通用约定?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2050961/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 21:57:36  来源:igfitidea点击:

Is "argv[0] = name-of-executable" an accepted standard or just a common convention?

c++cstandardsargv

提问by Mike Willekes

When passing argument to main()in a C or C++ application, will argv[0]always be the name of the executable? Or is this just a common convention and not guaranteed to be true 100% of the time?

main()在 C 或 C++ 应用程序中传递参数时,将argv[0]始终是可执行文件的名称?或者这只是一个常见的约定,并不能保证在 100% 的情况下都是正确的?

回答by paxdiablo

Guesswork (even educated guesswork) is fun but you really need to go to the standards documents to be sure. For example, ISO C11 states (my emphasis):

猜测(甚至是有根据的猜测)很有趣,但您确实需要查看标准文档才能确定。例如,ISO C11 声明(我的重点):

If the value of argcis greater than zero, the string pointed to by argv[0]representsthe program name; argv[0][0]shall be the null character if the program name is not available from the host environment.

如果 的值argc大于零,则指向的字符串argv[0]表示程序名称;argv[0][0]如果程序名在宿主环境中不可用,则应为空字符。

So no, it's only the program name if that name is available.And it "represents"the program name, not necessarily isthe program name. The section before that states:

所以不,如果该名称可用,它只是程序名称而且它“代表”的是程序名,不一定程序名。之前的部分指出:

If the value of argcis 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.

如果 的值argc大于零,则argv[0]通过argv[argc-1]inclusive的数组成员应包含指向字符串的指针,这些字符串在程序启动之前由主机环境赋予实现定义的值。

This is unchanged from C99, the previous standard, and means that even the valuesare not dictated by the standard - it's up to the implementation entirely.

这与之前的标准 C99 没有变化,这意味着即使这些也不是由标准规定的 - 这完全取决于实现。

This means that the program name can be empty if the host environment doesn'tprovide it, and anything else if the host environment doesprovide it, provided that "anything else" somehow represents the program name. In my more sadistic moments, I would consider translating it into Swahili, running it through a substitution cipher then storing it in reverse byte order :-).

这意味着,节目名称可以是空的,如果主机环境如果主机环境提供它,别的提供的,规定“任何东西”在某种程度上代表了程序名称。在我更虐待狂的时刻,我会考虑将它翻译成斯瓦希里语,通过替换密码运行它,然后以相反的字节顺序存储它:-)。

However, implementation-defined doeshave a specific meaning in the ISO standards - the implementation must document how it works. So even UNIX, which can put anything it likes into argv[0]with the execfamily of calls, has to (and does) document it.

然而,实现定义在 ISO 标准中确实有特定的含义——实现必须记录它是如何工作的。因此,即使UNIX,它可以把任何东西它喜欢到argv[0]exec家人通话的,有(并执行)文件就可以了。

回答by Richard Pennington

Under *nixtype systems with exec*()calls, argv[0]will be whatever the caller puts into the argv0spot in the exec*()call.

*nix同类型的系统exec*()调用,argv[0]将是任何来电是置于argv0现货exec*()通话。

The shell uses the convention that this is the program name, and most other programs follow the same convention, so argv[0]usually the program name.

shell 使用的约定是这是程序名,大多数其他程序遵循相同的约定,所以argv[0]通常是程序名。

But a rogue Unix program can call exec()and make argv[0]anything it likes, so no matter what the C standard says, you can't count on this 100% of the time.

但是一个流氓 Unix 程序可以调用exec()和制作argv[0]任何它喜欢的东西,所以无论 C 标准怎么说,你都不能 100% 指望这个时间。

回答by Richard Pennington

According to the C++ Standard, section 3.6.1:

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

argv[0] shall be the pointer to the initial character of a NTMBS that represents the name used to invoke the program or ""

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

So no, it is not guaranteed, at least by the Standard.

所以不,至少不能保证标准。

回答by Gregory Pakosz

ISO-IEC 9899 states:

ISO-IEC 9899 规定:

5.1.2.2.1 Program startup

If the value of argcis greater than zero, the string pointed to by argv[0]represents the programname; argv[0][0]shall be the null character if the program name is not available from the host environment. If the value of argcis greater than one, the strings pointed to by argv[1]through argv[argc-1]represent the program parameters.

5.1.2.2.1 程序启动

如果 的值argc大于零,则指向的字符串argv[0]代表程序名;argv[0][0]如果程序名在宿主环境中不可用,则应为空字符。如果 的值argc大于 1,则argv[1]通过指向的字符串argv[argc-1]表示程序参数

I've also used:

我也用过:

#if defined(_WIN32)
  static size_t getExecutablePathName(char* pathName, size_t pathNameCapacity)
  {
    return GetModuleFileNameA(NULL, pathName, (DWORD)pathNameCapacity);
  }
#elif defined(__linux__) /* elif of: #if defined(_WIN32) */
  #include <unistd.h>
  static size_t getExecutablePathName(char* pathName, size_t pathNameCapacity)
  {
    size_t pathNameSize = readlink("/proc/self/exe", pathName, pathNameCapacity - 1);
    pathName[pathNameSize] = '##代码##';
    return pathNameSize;
  }
#elif defined(__APPLE__) /* elif of: #elif defined(__linux__) */
  #include <mach-o/dyld.h>
  static size_t getExecutablePathName(char* pathName, size_t pathNameCapacity)
  {
    uint32_t pathNameSize = 0;

    _NSGetExecutablePath(NULL, &pathNameSize);

    if (pathNameSize > pathNameCapacity)
      pathNameSize = pathNameCapacity;

    if (!_NSGetExecutablePath(pathName, &pathNameSize))
    {
      char real[PATH_MAX];

      if (realpath(pathName, real) != NULL)
      {
        pathNameSize = strlen(real);
        strncpy(pathName, real, pathNameSize);
      }

      return pathNameSize;
    }

    return 0;
  }
#else /* else of: #elif defined(__APPLE__) */
  #error provide your own implementation
#endif /* end of: #if defined(_WIN32) */

And then you just have to parse the string to extract the executable name from the path.

然后您只需要解析字符串以从路径中提取可执行文件名称。

回答by ChrisF

This pagestates:

该页面指出:

The element argv[0] normally contains the name of the program, but this shouldn't be relied upon - anyway it is unusual for a program not to know its own name!

元素 argv[0] 通常包含程序的名称,但这不应该被依赖 - 无论如何,程序不知道自己的名称是不寻常的!

However, other pages seem to back up the fact that it is always the name of the executable. This onestates:

但是,其他页面似乎支持这样一个事实,即它始终是可执行文件的名称。这一篇说:

You'll notice that argv[0] is the path and name of the program itself. This allows the program to discover information about itself. It also adds one more to the array of program arguments, so a common error when fetching command-line arguments is to grab argv[0] when you want argv[1].

您会注意到 argv[0] 是程序本身的路径和名称。这允许程序发现有关自身的信息。它还向程序参数数组中添加了一个,因此获取命令行参数时的一个常见错误是在需要 argv[1] 时获取 argv[0]。

回答by Joe Mabel

I'm not sure whether it is a nearly universal convention or a standard, but either way you should abide by it. I've never seen it exploited outside of Unix and Unix-like systems, though. In Unix environments - and maybe particularly in the old days - programs might have significantly different behaviors depending on the name under which they are invoked.

我不确定它是几乎通用的约定还是标准,但无论哪种方式,您都应该遵守它。不过,我从未见过它在 Unix 和类 Unix 系统之外被利用。在 Unix 环境中 - 也许特别是在过去 - 程序可能具有显着不同的行为,具体取决于调用它们的名称。

EDITED: I see from other posts at the same time as mine that someone has identified it as coming from a particular standard, but I'm sure the convention long predates the standard.

编辑:我从与我同时期的其他帖子中看到有人认为它来自特定标准,但我确信该公约早于该标准。

回答by Polluks

If you start an Amiga program by Workbench argv[0] will not be set, only by CLI.

如果你通过 Workbench 启动 Amiga 程序 argv[0] 将不会被设置,只能通过 CLI。