我正在阅读C++常见问题解答,注意到其中一句话。
main()函数不能是内联的。
为什么会这样?
我正在阅读C++常见问题解答,注意到其中一句话。
main()函数不能是内联的。
为什么会这样?
*static_cast<int*>(0) = 10
也可以编译,但这并不意味着它是正确的……就像任何ODR违规一样,以及许多其他情况一样……它能够编译并不意味着它是合法的程序。 - David Rodríguez - dribeas因为标准这样规定:
[2003:3.6.1/3]
: 程序中不应使用函数main
(3.2)。main
的链接(3.5)是由实现定义的。声明main
为内联或静态的程序是非法的。名称main
并没有被保留。【例如:成员函数、类和枚举可以被称为main
,其他命名空间中的实体也可以。】
为什么要这样规定呢?因为它试图将main
的实现留给个别..好吧,实现者..尽可能多的自由决定,而不想限制实现只能在这里使用inline
,因为从实际上来看,这样做没有什么实际好处。
委员会中的朋友证实了这一点:
原则上讲,没有理由一个
inline
的main()
不能工作。[..]我可以有一个C++解释器,可以调用内联的main()
。[..]禁止使用inline
/static
main()
是为了避免混淆。我很难想象这个原则会有什么额外的解释,超出了[这个问答]中已经提到的内容。
顺便说一句,不要将inline
提示关键字与实际内联函数混淆。你可以标记一个函数为inline
,但它可能并不是真正物理上的内联。
因此,即使main
“不能被内联”是真的(严格来说这并不是真的,虽然像其他答案中解释的那样内联main
会非常笨拙和无意义),从理论上讲,它仍然可以很好地支持inline
提示关键字。
出于上述原因以及litb的回答,它并没有作用:这将会增加复杂性,却没有真正的好处。
inline
用于main
是微不足道的,因为它可以被忽略,因此不会限制任何实现,因此,标准禁止的这个可能原因站不住脚。抱歉,但我没有更多的答案可以提供了,我认为在inline
方面我们是同意的,这是毫无意义的。 - Cheers and hth. - Alfmain
,但这样做没有太多意义,因此不值得允许。 - Lightness Races in Orbitmain
具有必须与实现的运行时和主机操作系统交互的含义(因为它是程序入口点),因此对于一个委员会强制规定太多关于它的事情是没有意义的。请记住,其他函数的链接是由用户定义的,因此,事实上,标准在这里略微限制了main
,它说“听你的编译器供应商的,因为他们可以选择这个而不是你”。 :) - Lightness Races in Orbitmain()
函数,并且几乎总是动态链接的。因此,在典型情况下,它根本不可能工作。 - whitequark在C++中禁止直接调用main()函数,因此对它进行内联没有任何意义。
通常情况下,main()
函数从系统的init()
函数中调用。因此,需要确保main()
有唯一一个定义。
现在,如果我们可以将main()
函数inline
并包含在头文件中,那么每个翻译单元都会有不同的main()
定义。这是不被允许的。您可以在namespace
中声明main()
并对其进行inline
。但不能在全局范围内使用main()
。
inline
来实现这个。 - Lightness Races in Orbitstatic int main()
也是不好的形式:D) - Lightness Races in Orbitmain
函数的实例,那么你的观点是什么? - Thomas Matthewsmain
实例的限制仍然存在。尽管内联版本的main
可能是多余或无用的,但我认为没有理由不允许它。 - Thomas Matthews首先,您必须了解如何使用内联函数。
例如:
inline void f() {
int a = 3;
a += 3;
cout << a;
}
int main() {
f();
return 0;
}
编译器将会把它看作:
int main() {
int a = 3;
a += 3;
cout << a;
return 0;
}
看这个例子,你想如何使主函数立即内联化?
inline
函数和只有一个调用的main
函数有什么区别呢? - Thomas Matthewsinline
只是一个提示。它不执行函数内联。 - Lightness Races in Orbitmain
函数是无法有意义地内联的。这是荒谬的。虽然这需要链接器的一些帮助(例如全局优化),或者重新编译运行时库的一部分才能适用于每个应用程序,但这是完全可行的,没有技术问题。main
),inline
的提示效果是无关紧要的。
inline
的唯一保证作用是允许在两个或多个翻译单元中定义(相同的)具有外部链接的函数,即影响一个定义规则。main
来说是不合理的,因此没有理由使main
成为inline
。main
没有必要被标记为 inline
” 这个说法很有说服力,但并不能直接解释为什么它被设计成无法被标记为 inline
。 - Lightness Races in Orbitmain
函数的实现,当链接时会间接调用你的代码。从先验上看,我并没有看到在头文件中定义main函数和这种情况有显著的区别。 - Tim Seguinemain
放在头文件中的做法,这个头文件只会被一个翻译单元包含。事实上,我已经这样做了(示例请见github)。但是,在多个翻译单元中保证相同的定义是没有意义的。在我看来,也没有其他任何理由需要应用inline
。 - Cheers and hth. - Alfmain
函数不能被内联,参考@Tomalak Geret'kal的回答。如果标准中的限制被移除,则本回答讨论了内联main
函数的可能性。
内联定义inline
关键字是向编译器建议将函数内容嵌入到当前位置的一种方法。目的之一是消除调用和返回函数(子程序)时存在的开销。main
一次,如何链接取决于编译器。标准允许单个实例的内联函数。编译器允许将内联函数转换为对单个实例的函数调用。因此,编译器会忽略对main
函数的内联建议。main
函数实例。这就是棘手的部分,特别是涉及外部链接时。确保只有一个实例的一种处理方式是留下某个翻译信息,表明该翻译存在“main”函数,无论它是否被内联。需要注意的是,当调用内联函数时,编译器可以从具有外部链接的符号表中删除该函数,因为其想法是该函数不会被外部函数调用。
总结main
函数。已经存在将内联函数转换为单个实例的机制,并且可以识别函数的多个实例。当有指向内联函数的指针时,会创建函数的单个实例,因此它具有地址。此机制将满足main
具有地址的运行时库要求。对于main
函数的inline
情况,它将被忽略,但不应该有任何理由阻止这种语法(除了让人困惑)。毕竟,已经存在一些冗余的语法,例如将按值(复制)传递的参数声明为const
。main
。因此将inline
放在其中不会起到任何作用 - inline
仅在可以在程序中定义多次的函数上具有重要作用(所有定义将被视为只有一个定义,并且所有定义都需要相同)。inline
函数可以在程序中定义多次,并且inline
还可以使对标记为inline
的函数的调用尽可能快,因此标准要求在每个使用它的翻译单元中定义inline
函数。因此,如果inline
函数没有被当前翻译单元中的代码使用,则编译器通常会丢弃该函数的定义。对于main
来说这样做是完全错误的,这表明inline
和main
的语义是完全不兼容的。inline
并不意味着完全内联该函数。这完全取决于编译器的决定,当然,如果您从未调用main
(您也无法这样做),那么就没有什么可以内联的了。main
是内联的将需要它。从历史上看,C++不喜欢要求魔法。(但那是在模板之前。) - James Kanze
main
函数编译到其中。所以答案是因为您无法重新编译操作系统? - Kieren Johnstone