main函数可以重载吗?

问题描述 投票:0回答:6

main()
中存在两个有效版本的
C++

int main()  // version 1
int main(int argc, char **argv)  // version 2

但是两种重载不能同时共存。为什么不? (潜在用例:从终端运行程序时,如果没有传递参数,则调用第一个版本,否则调用第二个版本。)

编译器是否执行特殊检查以允许每个二进制文件只有一个版本?

c++ overloading program-entry-point
6个回答
66
投票

§3.6.1/2 (C++03) 说

实现不应预先定义

main
功能。 此功能应 不可超载。 应具有 返回类型为 int 类型,但除此之外 它的类型是实现定义的。 所有实现都应允许 以下 main 的定义:

   int main() { /* ... */ }
   int main(int argc, char* argv[]) { /* ... */ }

您可以使用其中任何一个。两者均符合标准。

此外,由于

char *argv[]
等同于
char **argv
,因此将
char *argv[]
替换为
char **argv
没有任何区别。


但是两个版本不能同时共存! (用例可以是这样的:从命令提示符运行二进制文件时,如果不传递任何参数,则应调用第一个版本,否则调用第二个版本)。

不。两个版本不能同时共存。一个程序只能有一个

main
函数。选哪一个,就看你的选择了。如果你想处理命令行参数,那么你必须选择第二个版本,否则第一个版本就足够了。另请注意,如果您使用第二个版本,并且不传递任何命令行参数,那么它没有任何害处。它不会导致任何错误。您只需相应地解释
argc
argv
,并根据它们的值,编写程序的逻辑和流程。


20
投票

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++ 标准相矛盾,这是有道理的,因为如果有多个,操作系统将不知道要调用哪个。检查只有一项不是在编译器中完成的,而是在链接器中完成的。


13
投票
C++ 标准 1998 和 2003 版的

第 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
,而使用哪一个则由程序员的实现偏好决定。


9
投票

Main 是在 C 时代定义的。它的设置更符合 printf 的规则。将

main
视为可变函数:

int main(...)

标准规定没有参数和两个指针参数是可以的。但是,如果实现想要提供更多参数,则可以自由地这样做。

不能有两个

main
的原因与不能在 C 程序中两次定义类似
printf
的函数的原因相同。当然,
printf
支持不同的参数,并根据存在的参数改变它的行为,但它并不是 C++ 意义上的重载。


7
投票

标准规定

main
不能超载。它没有被破坏,并且您不能拥有两个具有相同的未破坏名称的函数。我猜这会导致链接失败,但编译器可能需要添加显式检查以便给出更清晰的错误消息。

int main(int argc, char **argv)
int main()
应该是它的首选签名,但编译器可以自由接受具有不同参数的
main


0
投票

在 C++ 中不可能重载 main(),因为。编译器显示以下错误:

error C2731: 'main' : function cannot be overloaded 
© www.soinside.com 2019 - 2024. All rights reserved.