我读到C++标准禁止在main()
中进行递归,但是g++编译以下代码时没有任何警告:
int main()
{
main();
}
有人能解释一下这个吗?
我读到C++标准禁止在main()
中进行递归,但是g++编译以下代码时没有任何警告:
int main()
{
main();
}
有人能解释一下这个吗?
“使用”的定义为:在程序内部不应使用函数
main
(3.2)。
如果其名称出现在可能被评估的表达式中,则使用对象或非重载函数。
我会烹调鱼,并解释为什么这是被禁止的。在 C 或 C++ 程序开始运行之前,必须首先初始化 CRT(C 运行时库)。打开 stdin/out/err,调用初始化器等操作。有两种基本策略来完成此操作,这是一个繁重的平台实现细节。
程序的起始地址指向 CRT 初始化函数,最终调用 main()。常见于具有支持可执行文件中任意部分的高级加载程序的完整操作系统。
编译器将代码注入到 main() 函数中,以调用 CRT 初始化函数。起始函数始终为 main()。常见于具有受限制的加载程序功能的嵌入式平台。现在递归 main() 是个问题,CRT 启动代码将以不可预测的堆栈状态再次被调用。
main
之前而不是注入到main
中。编译器无论如何都会生成机器代码,没有理由在使用main
符号值作为地址后再这样做,无论可执行文件格式是否允许任意起始地址。 - T.J. Crowder这里声称:http://www.programmersheaven.com/mb/CandCPP/109711/109711/recursive-main/,确实被禁止:
标准规定如下:
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;
}
(注意,我加入了一个逃脱子句。即使是在假设情况下,我也无法编写无限递归的代码,因为它会对我重复执行。)
其他人已经解决了标准部分。然而,我想指出的是,如果您在至少一个这些错误中使用-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]
void f() { f(); } int main() { f(); }
你是在main()
函数中进行递归吗?有些人会说“不是”,有些人会说“是”。你是在进入main()
函数中进行递归吗?没有人会说“是”。因此,后者更清晰明了。 - j_random_hacker