iam*_*ind 67 c++ program-entry-point overloading
main()
存在2个有效版本C++
:
int main() // version 1
int main(int argc, char **argv) // version 2
Run Code Online (Sandbox Code Playgroud)
但两种重载都不能同时共存.为什么不?(潜在用例:从终端运行程序时,如果没有传递参数,则调用第一个版本,否则第二个版本被调用.)
编译器是否执行特殊检查以允许每个二进制文件只有一个版本?
Naw*_*waz 65
§3.6.1/ 2(C++ 03)说
实现不应预定义该
main
功能.此功能不应过载.它应该具有int类型的返回类型,否则其类型是实现定义的.所有实现都应允许以下两个主要定义:
int main() { /* ... */ }
int main(int argc, char* argv[]) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)
你可以使用它们中的任何一个.两者都符合标准.
而且,因为char *argv[]
相当于char **argv
,取而代之char *argv[]
的char **argv
是没有任何区别.
但这两个版本不能同时共存!(用例可以是:从命令提示符运行二进制文件时,如果不传递参数,则应调用第一个版本,否则调用第二个版本).
不可以.两个版本不能同时共存.一个程序可以只有一个main
功能.哪一个,取决于您的选择.如果要处理命令行参数,那么您必须选择第二个版本,否则第一个版本就足够了.另请注意,如果您使用第二个版本,并且不传递任何命令行参数,那么它就没有任何损害.它不会导致任何错误.您只需要解释argc
并argv
相应地根据它们的价值,编写程序的逻辑和流程.
Ski*_*izz 20
Windows和Unix有:
int main(int argc, char **argv, char **envp)
Run Code Online (Sandbox Code Playgroud)
和Win32应用程序有:
int WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);
Run Code Online (Sandbox Code Playgroud)
和MacOS有:
int main(int argc, char **argv, char **envp, char **apple)
Run Code Online (Sandbox Code Playgroud)
不要忘记,这main
通常不是操作系统在执行程序时调用的第一件事.该main
函数是运行时环境调用的函数.要执行的第一条指令的地址通常在某些元数据中声明,通常在可执行文件的开头处.
就我所知,只要只有一个,这一切都与C/C++标准相矛盾,这是有道理的,因为如果有多个操作系统,操作系统就不知道应该调用哪个.检查编译器中只有一个没有完成,它是在链接器中完成的.
Alo*_*ave 13
C++标准1998和2003版本的第3.6.1.2节规定:
实现不应预定义主函数.此功能不应过载.它应该具有int类型的返回类型,否则其类型是实现定义的.
进一步,
ISO C++标准(ISO/IEC 14882:1998)特别要求main返回int.它对格式良好的程序有明确的"应当"约束.
第3.6.1节2:
它的返回类型应为int,否则其类型是实现定义的.所有实现都应允许以下两个主要定义:
int main() { /* … */ }
Run Code Online (Sandbox Code Playgroud)
和
int main(int argc, char* argv[]) { /* … */ }
Run Code Online (Sandbox Code Playgroud)
因此main
,标准允许使用哪个版本,使用哪个版本作为程序员的实现首选项.
主要是在C天定义的.它的设置更符合printf的规则.考虑main
作为一个varadic函数:
int main(...)
Run Code Online (Sandbox Code Playgroud)
标准说没有参数和两个指针参数是可以的.但是,如果实现想要提供更多参数,则实现可以自由地执行.
您不能拥有两个main
s的原因与您printf
在C程序中无法两次定义like函数的原因相同.当然,printf
支持不同的参数并根据哪些参数改变它的行为,但它不会在C++的术语意义上重载.
标准说main
不能超载.它没有被破坏,你不能拥有两个具有相同unmangled名称的函数.我想这会导致链接失败,但编译器可能希望添加显式检查以便提供更清晰的错误消息.
int main(int argc, char **argv)
并且int main()
应该是它的首选签名,但编译器可以自由地接受main
具有不同参数的a.