main()
中存在两个有效版本的C++
:
int main() // version 1
int main(int argc, char **argv) // version 2
但是两种重载不能同时共存。为什么不? (潜在用例:从终端运行程序时,如果没有传递参数,则调用第一个版本,否则调用第二个版本。)
编译器是否执行特殊检查以允许每个二进制文件只有一个版本?
§3.6.1/2 (C++03) 说
实现不应预先定义
功能。 此功能应 不可超载。 应具有 返回类型为 int 类型,但除此之外 它的类型是实现定义的。 所有实现都应允许 以下 main 的定义:main
int main() { /* ... */ }
int main(int argc, char* argv[]) { /* ... */ }
您可以使用其中任何一个。两者均符合标准。
此外,由于
char *argv[]
等同于 char **argv
,因此将 char *argv[]
替换为 char **argv
没有任何区别。
但是两个版本不能同时共存! (用例可以是这样的:从命令提示符运行二进制文件时,如果不传递任何参数,则应调用第一个版本,否则调用第二个版本)。
不。两个版本不能同时共存。一个程序只能有一个
main
函数。选哪一个,就看你的选择了。如果你想处理命令行参数,那么你必须选择第二个版本,否则第一个版本就足够了。另请注意,如果您使用第二个版本,并且不传递任何命令行参数,那么它没有任何害处。它不会导致任何错误。您只需相应地解释 argc
和 argv
,并根据它们的值,编写程序的逻辑和流程。
Windows 和 Unix 有:
int main(int argc, char **argv, char **envp)
Win32 应用程序具有:
int WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);
MacOS 有:
int main(int argc, char **argv, char **envp, char **apple)
不要忘记,
main
通常不是操作系统在执行程序时首先调用的。 main
函数是运行时环境调用的函数。要执行的第一条指令的地址通常在一些元数据中声明,通常在可执行文件的开头。
据我所知,只要只有一个,上述内容都不与 C/C++ 标准相矛盾,这是有道理的,因为如果有多个,操作系统将不知道要调用哪个。检查只有一项不是在编译器中完成的,而是在链接器中完成的。
第 3.6.1.2 节指出:
实现不应预定义主函数。 此函数不得重载。它应具有 int 类型的返回类型,但除此之外,其类型是实现定义的。
此外,
ISO C++ 标准 (ISO/IEC 14882:1998) 特别要求 main 返回 int。它对格式良好的程序有明确的“应”约束。
第 § 3.6.1 节 ¶ 2:
它的返回类型应为 int,但除此之外,其类型是实现定义的。所有实现都应允许以下两个 main 定义:
int main() { /* … */ }
和
int main(int argc, char* argv[]) { /* … */ }
因此,标准允许使用两个版本的
main
,而使用哪一个则由程序员的实现偏好决定。
Main 是在 C 时代定义的。它的设置更符合 printf 的规则。将
main
视为可变函数:
int main(...)
标准规定没有参数和两个指针参数是可以的。但是,如果实现想要提供更多参数,则可以自由地这样做。
不能有两个
main
的原因与不能在 C 程序中两次定义类似 printf
的函数的原因相同。当然,printf
支持不同的参数,并根据存在的参数改变它的行为,但它并不是 C++ 意义上的重载。
标准规定
main
不能超载。它没有被破坏,并且您不能拥有两个具有相同的未破坏名称的函数。我猜这会导致链接失败,但编译器可能需要添加显式检查以便给出更清晰的错误消息。
int main(int argc, char **argv)
和 int main()
应该是它的首选签名,但编译器可以自由接受具有不同参数的 main
。
在 C++ 中不可能重载 main(),因为。编译器显示以下错误:
error C2731: 'main' : function cannot be overloaded