中main()
存在2个有效版本C++
:
int main() // version 1
int main(int argc, char **argv) // version 2
但是,两个过载不能同时存在。为什么不?(可能的用例:从终端运行程序时,如果未传递任何参数,则调用第一个版本,否则调用第二个版本。)
编译器是否执行特殊检查以允许每个二进制文件仅允许一个版本?
中main()
存在2个有效版本C++
:
int main() // version 1
int main(int argc, char **argv) // version 2
但是,两个过载不能同时存在。为什么不?(可能的用例:从终端运行程序时,如果未传递任何参数,则调用第一个版本,否则调用第二个版本。)
编译器是否执行特殊检查以允许每个二进制文件仅允许一个版本?
C
标签,因为main()
也允许使用多个版本C
。此外,void main()
C ++不支持,但大多数情况下它是有效的C
。但是,提到C++
这个问题,我已经站在立场上了。
void main()
如果您谈论的是标准C(C89,C90,C99),它也不是有效的C。
argc
则为1,并argv
包含指向程序名称的指针,后跟一个空指针。因此,即使您可以重载它,也不会想要这种行为,因为即使没有参数,仍然会有一个argc / argv对。
Answers:
§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
相应,并根据自己的价值,你写的逻辑和程序的流程。
This function shall not be overloaded
清楚说明其C ++。毕竟,C不支持重载的任何功能。
main
并不是真正的程序入口点,它是第一个(main)要调用的函数,但是必须在 main
调用之前进行静态初始化。我怀疑,DOS / Windows系统有不同的入口点的应用程序(如果有不同的可执行文件格式可能是),我也怀疑,在的情况下wmain
,_tmain
与WinMain
该程序不包含一个普通的main
功能(在库定义在联)转发该呼叫......但我必须有一个Windows环境实际测试,所以我不会断言这是真实的或者
main
库代码中隐藏了一个普通的函数。在_tWinMain
你看到的东西是不是官方的切入点,它只是尽可能的入口点你的代码而言。
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 ++标准相抵触,这是有道理的,因为如果有多个,操作系统将不知道要调用哪个。在编译器中不检查只有一个,在链接器中检查。
WinMain
吗?由于进入函数被定义为main
...(除了MSVC中所有其他不兼容的内容。)
main
为您创建一个函数,该函数在调用您的WinMain
函数之前进行一些特定的初始化。程序的入口点仍然是main
,只是在这种情况下它不是您的主要入口。似乎与第3.6.1 / 2节矛盾。实现不应预定义主要功能。,但如果他们可以确保它不会影响您的程序(即,如果您确实定义了main
它使用的是您的版本而不是其自己的版本),那么它的行为就好像是if一样,就足够了。
main
如果需要,大多数单元测试框架都将为您提供。这时,它成为关于main
编译器生成还是链接为库的哲学讨论。。和所有是灰色的,我不会真的在意它,我已经在其他地方看到更糟糕的事情... Symbian C ++的人是一个
main
,按照标准是可以的。:)
C ++ Standard 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
,标准允许两个版本的版本,并且使用哪个版本作为程序员的实现偏好。
implementation detail
在编译器和工具集的上下文中或以通用方式显式使用时感到有点困惑。以通用方式使用它,您做到了!:)
Main定义于C天。它按照printf的规则进行设置。考虑main
为方差函数:
int main(...)
该标准说没有参数和两个指针参数都可以。但是,如果实现要提供更多的参数,则实现是可以自由提供的。
您不能拥有两个main
s的原因与您无法printf
在C程序中两次定义一个类似函数的原因相同。当然,printf
支持不同的参数,并根据其中存在哪些参数来更改其行为,但是就C ++而言,它不会超载。
...
允许调用者改变参数数量,但是可以期望OS加载程序始终main
使用相同数量的参数进行调用。如果程序未明确列出(int argc, char* argv[])
大多数实现,则无论如何都会隐式地考虑它们。它们要放入的寄存器和/或堆栈可能在调用main之前加载了它们的值。值得庆幸的是,您不会收到有关未使用变量的警告:-)。因此,与“ printf ...改变其行为”相比,main可能是恒定的(但正式意义上是确定的)
标准说main
不能过载。它不会被破坏,并且不能有两个具有相同名称的函数。我猜这将导致链接失败,但是编译器可能希望添加显式检查,以便提供更清晰的错误消息。
int main(int argc, char **argv)
并且int main()
应该是它的首选签名,但是编译器可以自由接受main
带有不同参数的。
main
始终声明extern "C"
,无论您是否明确编写?
main
直接从任何上下文(甚至是操作系统)中调用,因为操作系统必须调用专门生成的静态初始化main之前的代码-即它是一个实现细节,详细说明了如何进行改编,可以进行特殊改编,也可以完全不进行改编。
main()
直到名称在全局范围内,名称才会混乱;第二件事是,当您main()
在一个文件中声明多个具有不同参数的文件时,编译器会给出以下错误:error: declaration of C function int main() conflicts with ...
main
视为C函数,而不是一般而言“它不会被视为C函数而被破坏”或“它始终是extern "C"
”。特别是在平台(OS)中,称为C样式函数main
作为程序入口点,C ++编译器将被迫将您的main
函数修改为其他内容,并向_main
符号添加静态初始化。未指定此名称的原因是因为它正在处理与OS的接口,并且C ++标准无法强制执行该操作。
因为不能在C ++中重载main()。编译器显示以下错误:
error C2731: 'main' : function cannot be overloaded