C ++声明'main'作为函数的引用?

时间:2015-02-12 18:00:55

标签: c++ reference main language-lawyer iso

如果我将main定义为函数的引用怎么办?

#include<iostream>
#include<cstring>

using namespace std;

int main1()
{
    cout << "Hello World from main1 function!" << endl;
    return 0;
}

int (&main)() = main1;

会发生什么?我在一个在线编译器中测试了错误“Segmentation fault”:

here

在VC ++ 2013下,它会在运行时创建程序崩溃!

将编译将函数指针的数据作为代码调用的代码,该代码将在启动时立即崩溃。

我还想要一个关于此的ISO C ++标准引用。

如果你想根据某些宏定义2个入口点中的任何一个,这个概念会很有用:

int main1();

int main2();

#ifdef _0_ENTRY
int (&main)() = main1;
#else
int (&main)() = main2;
#endif

5 个答案:

答案 0 :(得分:16)

这不是一个符合要求的C ++程序。 C ++要求(第3.6.1节)

  

程序应包含一个名为main

的全局函数

您的程序包含一个名为main的全局非函数,它引入了与所需的main函数的名称冲突。


这样做的一个理由是它允许托管环境在程序启动期间对main进行函数调用。它不等同于源字符串main(args),它可以是函数调用,函数指针取消引用,在函数对象上使用operator(),或构造类型为main的实例。不,main必须是一个功能。

另外需要注意的一点是,C ++标准从未说明main实际上是什么类型,并阻止您观察它。因此,实现可以(并且!)重写签名,例如添加您省略的任何int argc, char** argv, char** envp。显然,您无法知道为main1main2执行此操作。

答案 1 :(得分:7)

  

如果您想根据某些宏

定义2个入口点中的任何一个,这将非常有用

不,不是真的。你应该这样做:

int main1();
int main2();

#ifdef _0_ENTRY
   int main() { return main1(); }
#else
   int main() { return main2(); }
#endif

答案 2 :(得分:3)

由于CWG issue 1886的解决方案很快就会变得非常不明确,目前正处于初步准备状态。 status,除其他外,还为[basic.start.main]添加以下内容:

  

在全局范围内声明变量main的程序   使用C语言链接(在任何名称空间中)声明名称main   不良形成。

答案 3 :(得分:1)

在实践中会发生什么在很大程度上取决于实施。

在你的情况下,你的编译器显然在伪装&#34;中将该引用实现为&#34;指针。除此之外,指针还有外部链接。即您的程序导出一个名为main的外部符号,该符号实际上与指针占用的数据段中的内存位置相关联。链接器在不过多考虑的情况下,将内存位置记录为程序的入口点。

稍后,尝试将该位置用作入口点会导致分段错误。首先,该位置没有有意义的代码。其次,仅仅尝试将控制权传递给数据段内的某个位置可能会触发数据执行保护&#34;平台的机制。

通过这样做,您显然希望参考资料得到优化,即main将成为main1的另一个名称。在你的情况下,它没有发生。该参考作为一个独立的外部对象幸存下来。

答案 4 :(得分:0)

看起来你已经回答了关于会发生什么的问题。

至于为什么,在代码中main是一个函数的引用/指针。这与功能不同。如果代码调用指针而不是函数,我会期望段错误。