【发布时间】:2021-07-01 21:40:16
【问题描述】:
我是 C++ 新手,我见过许多 C++ 编译器会自动将 int argc,char* argv 作为参数传递给主函数,但它们是在哪里定义的? 有点好奇想知道。
【问题讨论】:
-
有趣的问题。
标签: c++
我是 C++ 新手,我见过许多 C++ 编译器会自动将 int argc,char* argv 作为参数传递给主函数,但它们是在哪里定义的? 有点好奇想知道。
【问题讨论】:
标签: c++
这些通常由外壳程序提供,或者更具体地说,由父进程提供。那就是父进程可以决定要传递哪些参数(如果有)。这些出现在argc/argv。请参阅exec 系列函数,以了解从父进程角度看的示例。还有用于启动进程的内核版本。
它们是由操作系统和进程间机制专门定义并最终提供的。这是C++ standard that defines the main() function 的一部分。
这种机制继承自相同的 C 版本,这在很大程度上是 UNIX 本身设计的副产品,因为 C 和 UNIX 是串联产生的。
【讨论】:
请阅读良好的 C++ programming book,然后参阅 this C++ reference 和一些 C++ 标准,如 n3337 或更好。
您的编译器(例如GCC)没有将argc 和argv 参数添加到main。使用gcc -Wall -Wextra -g,它检查main 是否有这些参数(但您可以在Linux 上定义int main(void) 或int main(int argc, char**argv, char**environ))。重要的是main 的签名,而不是参数的确切名称(只是它们的类型和编号)。
您的操作系统(例如 Linux 及其kernel)正在将这些传递给您的main。在 Linux 上,一个程序由execve(2) 启动,该系统调用将参数传递给main。从技术上讲,调用堆栈的初始布局在 ABI 中指定。一些crt0 初始化代码正在调用main(和静态构造函数)。该初始化代码是用汇编程序编写的。读好OS textbook。
有时,C++ 以独立模式使用。然后,没有main 和其他约定适用。一个典型的例子是当你用 C++ 编写一个操作系统内核时(例子见OSDEV)
由于GCC、Linux kernel 和GNU libc 是免费软件,您可以下载它们的源代码并进行研究(并在以后对其进行改进)。另见LinuxFromScratch。
研究 - 获取灵感 - 现有 C++ 开源项目的源代码,如 Qt、FLTK、RefPerSys 等。对于 RefPerSys,请通过电子邮件联系我至 basile@starynkevitch.net
【讨论】:
我是 C++ 新手,我看到许多 C++ 编译器会自动将 int argc,char* argv 作为参数传递给主函数,但它们是在哪里定义的?
它们是 C 和 C++ 标准的一部分。将它们提供给main() 函数的确切方式将取决于操作系统。例如,在类 Unix 系统中,fork() 和 exec() 的某个版本的组合用于创建一个新进程,然后在该新进程的上下文中加载并执行您的程序,并将参数传递给新程序过去了。其他操作系统将以其他方式启动新进程,但argc 和argv 参数仍将来自启动您的程序的程序,无论是面向命令的shell、某些GUI 桌面管理器还是其他。
【讨论】: