为什么C++中的main()无法内联?

jon*_*jon 68 c++ program-entry-point inline

我正在阅读C++常见问题,我注意到了一句话.

main()不能内联.

为什么是这样?

sep*_*p2k 104

在C++中,在代码中调用main函数是不合法的,因此无法进行内联.

  • 这个*是*的原因,想一想. (17认同)
  • @iammilind:`*的static_cast <INT*>(0)= 10`编译过了,这并不意味着它是正确的......因为是任何ODR违规的情况下,和许多其他的事情......事实它编译并不意味着它是一个合法的程序. (17认同)
  • 但是,调用`main()`中的`main()`进行编译.http://www.ideone.com/vqUgu (7认同)
  • @iammilind:声明"它编译"需要上下文.因为编译标准当然不需要它,并且事实上它并不能在所有情况下编译. (5认同)
  • *叹气*对于任何想知道的人,op在评论中说"出于某种原因"然后我评论回答他,但他删除了他的.不酷,操作. (4认同)
  • @ sepp2k:看我的回答.但简而言之,机器代码内联与问题无关,但从技术上讲,它可以在运行时库的调用中以两种不同的方式内联.然而,它没有完成,因为没有优势.:-) (4认同)
  • -1"没有办法可以被内联"是不正确的.另外,这只是原因的最小部分,是一个相当无关紧要的部分.:-) (3认同)

Lig*_*ica 66

因为标准如此说:

[2003: 3.6.1/3]:函数main不得在程序中使用(3.2).main的链接(3.5)是实现定义的.声明main为内联或静态的程序格式不正确.名称main不以其他方式保留.[示例:成员函数,类和枚举可以称为main,其他名称空间中的实体也可以称为main.]

为什么这么说呢?因为它试图尽可能多地留下main对个人的实现......好吧,实现 ......尽可能实现,并且不希望通过要求inline在有效期间无效的情况下限制实现.


委员会的朋友证实了这一点:

inline main()本身就没有理由不行.[..]我可以有一个可以调用内联的C++解释器main().[...] [但] inline/ static main()是被禁止的,以期避免混淆.我发现很难想象这个理由会对[本问答]中已经说过的内容有所帮助.


顺便说一句,不要将inlinehint关键字与实际的内联函数混淆.您可以标记一个函数inline,但它可能没有实际内联.

因此,即使main"无法内联"(并且严格来说这不是真的,尽管内main联会像其他答案中所解释的那样尴尬和毫无意义),它理论上仍然可以支持inline提示关键字.

它不是出于上述原因,并且在litb的回答中:它会使事情变得复杂,没有真正的好处.

  • +1引用标准.但是,这可能无法完全回答OP的问题; 到目前为止,除了你的帖子,我还没有看到任何合理的答案. (4认同)
  • @meet:为什么不应该?与用户定义的其他函数不同,"main"具有必须与实现的运行时和主机操作系统交互的含义(因为它是程序入口点),因此对于一个人们委员会来说太过分了它.回想一下,其他函数的链接是用户定义的,事实上,标准_is_稍微约束`main`,通过说"听你的编译器供应商,因为_they_得到选择这个而不是你".:) (2认同)

Rin*_*ing 27

C运行时库需要找到此符号才能"知道"要运行的函数.


Kar*_*ath 17

你不能直接调用main()(它在c ++中被禁止),所以没有内联点.

  • "毫无意义"是不足以完全取缔某些东西的理由.比这还要多一些. (5认同)

iam*_*ind 14

通常main()从系统init()函数调用.因此,需要有可以只有一个定义main().

现在,如果我们可以inlinemain()函数包含在头文件中,那么对于每个翻译单元都会有不同的定义main().这是不允许的.你可以main()在a namespaceinline它中声明.但不是全球性的main().


nir*_*mus 10

首先,您必须了解内联工作的功能

例:

 inline void f() {
     int a  = 3;
     a += 3;
     cout << a;
 }

 int main() {
      f();
      return 0;
 }
Run Code Online (Sandbox Code Playgroud)

看起来像编译器:

 int main() {
        int a  = 3;
        a += 3;
        cout << a;
        return 0;
 }
Run Code Online (Sandbox Code Playgroud)

看看这个例子,你想如何制作主内联?此方法立即内联.

  • 那么处理只有一次调用的`inline`d函数和只有一次调用的`main`函数有什么区别呢? (2认同)

Che*_*Alf 7

其他人已经注意到,main在机器代码级别上无法有意义地调用调用.那是垃圾.它需要链接器的一些帮助(如全局优化)或者每个应用程序重新编译一些运行时库,但这是非常可行的,这里没有技术问题.

然而,优选地应该内联的调用的暗示效果与inline仅被调用一次并且在最高控制级别的函数无关main.

唯一保证效果inline是,以允许在两个或多个翻译单元(相同)定义的外部链接函数,即影响了一个定义规则.

实际上,这允许将定义放在头文件中,并将其放在头文件中也是保证相同定义的实际必要条件.

这没有意义main,所以没有理由main这样做inline.


Tho*_*ews 7

根据main@Tomalak Geret'kal的回复,C++标准说该功能无法内联.该回复讨论了main函数内联的可能性,是否删除了标准中的限制.

内联
定义inline关键字是编译器在原位粘贴函数内容的建议.一个目的是消除调用和返回函数(子例程)中存在的开销.

内联的一个重要情况是指向函数的指针.在这种情况下,必须至少有一个该函数的静态副本.在这种情况下,链接器可以解析内联函数的"外部链接",因为有一个静态版本.

需要注意的是,编译器和链接器确定是否粘贴内容或调用函数的单个实例.

另外值得注意的是,编程器也可以内联未由程序员标记的函数.

内联的主要功能
由于只有一个的调用main允许的,怎么就被链接到了编译器.标准允许单个内联函数实例.允许编译器将inlined函数转换为对单个实例的函数调用.因此编译器会忽略main函数的内联建议.

编译器和链接器必须确保只main存在内联函数的一个实例.这是棘手的部分,特别是外部链接.确保一个实例的一个过程是保留翻译具有"主要"功能的信息,无论其是否被内联. 注意:当调用内联函数时,允许编译器从符号表中删除函数以进行外部链接,因为这个想法是函数不会被外部函数调用.

总结
从技术上讲,没有任何东西阻止main函数被内联.的机械已存在用于将内联的函数成单实例和用于识别功能的多个实例.当存在指向内联函数的指针时,会生成一个函数的单个实例,因此它具有一个地址.该机器将满足运行时库main有地址的要求.在的情况下,inlinemain功能,它会被忽略,但不应该有任何理由阻止这句法(除混乱的人).毕竟,已经存在多余的语法案例,例如声明由value(copy)传递的参数const.

"这只是我的意见,我可能是错的." - 喜剧演员丹尼斯米勒.


Joh*_*itb 6

您只能定义main一次.因此,put inline不会用于任何目的 - inline只有在程序中可以多次定义的函数具有重要意义(所有定义都将被视为只有一个定义,并且所有定义都必须相同).

因为inline函数可以在程序中多次定义,并且inline还用于inline尽可能快地调用带标记的函数,所以标准要求inline在使用它的每个转换单元中定义函数.因此编译器通常会抛弃函数的定义(如果它是,inline并且当前转换单元中的代码不使用该函数).要做到这一main点将是完全错误的,这表明inline和语义main完全不相容.

请注意,标题"为什么C++中的main()无法内联?"中的问题?你从标准中引用的陈述涉及不同的事情.您正在询问是否可以内联函数,这通常被理解为将被调用函数的代码完全或部分地插入到调用函数中.仅仅标记一个函数inline并不意味着完全内联函数.这完全是编译器的决定,当然如果你从不打电话main(而且你不能这样做)那么就没有什么可以内联的了.

  • @James:是一个括号,是的,但是实施被允许做任何想要的魔法.<G> (2认同)