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

C++ declare 'main' as a reference to function?

如果我将 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

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

A program shall contain a global function called main

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


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

另一件需要注意的事情是 C++ 标准从不说明 main 的类型实际上是什么,并且阻止您观察它。因此,实现可以(并且确实!)重写签名,例如添加您省略的 int argc, char** argv, char** envp 中的任何一个。显然它不知道为您的 main1main2.

执行此操作

This would be useful if you want to define either of 2 entry-points depending on some macro

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

int main1();
int main2();

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

由于 CWG issue 1886 的决议,目前处于 "tentatively ready" 状态,这很快就会变得明显不正确,它在 [[=17] 中添加了以下内容=]]:

A program that declares a variable main at global scope or that declares the name main with C language linkage (in any namespace) is ill-formed.

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

在您的情况下,您的编译器显然将该引用实现为 "pointer in disguise"。除此之外,指针还有外部链接。 IE。您的程序导出一个名为 main 的外部符号,它实际上与指针占用的数据段中的内存位置相关联。链接器没有过多地查看它,而是将该内存位置记录为程序的入口点。

稍后,尝试将该位置用作入口点会导致分段错误。首先,该位置没有有意义的代码。其次,仅仅尝试将控制权传递到数据段内的某个位置可能会触发平台的 "data execution protection" 机制。

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

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

至于为什么,在您的代码中 main 是函数的 reference/pointer。这与函数不同。如果代码调用的是指针而不是函数,我预计会出现段错误。