我读到 C++ 标准禁止在 中递归main()
,但 g++ 编译以下代码没有任何抱怨:
int main()
{
main();
}
任何人都可以澄清这一点吗?
根据 3.6.1/3 中的标准,它不是:
该功能
main
不得在程序中使用 (3.2)
used being的定义:
如果对象或非重载函数的名称出现在可能求值的表达式中,则使用该对象或非重载函数。
我会做鱼并解释为什么这是禁止的。在 C 或 C++ 程序可以开始运行之前,必须首先初始化 CRT。打开 stdin/out/err,调用初始化程序,诸如此类。有两种基本策略可以完成这项工作,一个是繁重的平台实现细节。
程序的起始地址指向 CRT init 函数,该函数最终调用 main()。在功能齐全的操作系统上很常见,这些操作系统有一个花哨的加载器,可以支持可执行映像中的任意部分。
编译器将代码注入到调用 CRT 初始化函数的 main() 函数中。启动函数始终是 main()。在加载器功能有限的嵌入式平台上很常见。递归 main() 现在是一个问题,CRT 启动代码将被再次调用,堆栈状态不可预测。
这里的说法是它确实是明确禁止的:
好吧,标准规定:
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;
}
(注意我添加了一个退出子句。我什至不能假设编码无限递归,它在我身上重复。)
这是不合法的。阅读 3.6.1-3:
函数 main 不得在程序中使用(3.2)。main 的链接(3.5)是实现定义的。将 main 声明为 inline 或 static 的程序是格式错误的。名称 main 没有保留。[示例:成员函数、类和枚举可以称为 main,其他命名空间中的实体也可以。]
其他人已经解决了标准部分。但是,我想指出,如果您使用-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]