我读到C ++标准禁止main()
中的递归,但是g ++编译以下代码而没有抱怨:
int main()
{
main();
}
任何人都可以澄清这个吗?
答案 0 :(得分:50)
根据3.6.1 / 3中的标准,它不是:
不得使用函数
main
(3.2)程序中的
使用的定义为:
对象或非超载 如果其名称出现在可能评估的表达式中,则使用该函数。
答案 1 :(得分:37)
我会做鱼并解释为什么这是 verboten 。在C或C ++程序开始运行之前,必须首先初始化CRT。打开stdin / out / err,调用初始值设定项,这类事情。完成这项工作有两个基本策略,一个沉重的平台实现细节。
程序的起始地址指向CRT init函数,该函数最终调用main()。在功能齐全的操作系统上很常见,它有一个花哨的加载器,可以支持可执行映像中的任意部分。
编译器将代码注入调用CRT初始化函数的main()函数中。 start函数始终为main()。常见于具有有限加载器功能的嵌入式平台递归main()现在是一个问题,CRT启动代码将以不可预测的堆栈状态再次被调用。
答案 2 :(得分:22)
声明here确实是特别禁止的:
嗯,标准声明:
<强> 3.6.1.3 强>
“函数main不得在程序中使用。”<强> 5.2.2.9 强>
“允许递归调用,但名为main的函数除外”
当然,您可以这样做:
int main(int argc, char* argv[]) {
return foo(argc, argv);
}
int foo(int argc, char* argv[]) {
if (some_condition) {
return foo(argc, argv);
}
return 0;
}
(注意我添加了一个get-out子句。我甚至不能假设代码无限递归,它在我身上重复。)
答案 3 :(得分:9)
这不合法。阅读3.6.1-3:
不得使用函数main (3.2)在一个程序中。联系 (3.5)主要是 实现定义。一个程序 声明main为内联或静态 是不正确的。主要名称不是 另外保留。 [例子:成员 函数,类和枚举 可以称为主要,也可以称为实体 其他名称空间。 ]
答案 4 :(得分:1)
其他人已经解决了标准问题。但是,我想请注意,如果您使用-pedantic-errors
至少有一个错误(取决于main
签名),g ++(至少4.6.2)将拒绝此操作:
error: ISO C++ forbids calling ‘::main’ from within program [-pedantic]
error: ISO C++ forbids taking address of function ‘::main’ [-pedantic]