|
1
30
如果您想在托管C++实现中运行您的程序,则需要
如果您使用“executionstartsintheconstructorofmyglobal object”,请注意,您会遇到许多与在不同转换单元中定义的命名空间作用域对象的构造顺序相关的问题(所以
是
入口点?答案是:您将有多个入口点,而首先执行的入口点是未指定的!)在C++ 03中,你甚至不能保证
如果正确地开始执行
正如评论中提到的那样
是
但是有几个系统隐藏
对于这个系统的用户来说,完全隐藏了
这不存在上面提到的构造顺序不明的问题。它们的好处是可以与不同形式的更高级别入口点一起工作。例如,Windows GUI程序在
|
|
|
2
4
对! 你可以不用main。 免责声明:你问是否可能,而不是是否应该这样做。这是一个完全不受支持的坏主意。我自己也这么做了,原因是我不想谈,但我不建议这样做。我的目的不是摆脱main,但它也可以做到这一点。 基本步骤如下:
让它编译和链接可能很困难;困难程度取决于哪个编译器和哪个编译器版本。 补充 我刚刚在Visual Studio 2008中完成了这项工作,下面是让它与编译器一起工作所需的具体步骤。
(*)不能使用运行时DLL,必须静态链接到运行时库。
补充 我移除了超常的退出呼叫和关于生命的模糊,因为我认为我们都能理解移除主的后果。 超坏死 我刚刚找到这个答案,并阅读了它和约翰迪布林的反对意见如下。很明显,我没有解释上面的过程做什么,以及为什么它确实从程序中完全删除main。 约翰断言在阴极射线管中“总有一个主管”。这些话并不完全正确,但声明的精神是正确的。Main不是CRT提供的函数,您必须自己添加它。对该函数的调用在CRT提供的入口点函数中。 每个C/C++程序的入口点是一个名为CRT0的模块中的一个函数。我不确定这是一个约定还是语言规范的一部分,但是我遇到的每一个C/C++编译器都使用它。这个函数主要做三件事:
在上面的例子中,调用是_tmain,但这是一些宏魔术,允许“main”可以有各种形式,其中一些在本例中是VS-specific。 上面的过程是从CRT中删除模块crt0,并用一个新的模块替换它。这就是为什么不能使用运行时DLL,该DLL中已经有一个函数的入口点名称与我们要添加的相同(2)。静态链接时,CRT是.lib文件的集合,链接器允许您完全重写.lib模块。在这种情况下,只有一个功能的模块。 我们的新程序包含股票CRT,减去它的CRT0模块,但有一个我们自己创建的CRT0模块。在那里我们取消了对main的呼叫。所以哪里都没有主食! (2)您可能认为可以通过重命名crt0.c文件中的入口点函数并在链接器设置中更改入口点来使用运行时DLL。但是,编译器不知道入口点的更改,并且DLL包含对您没有提供的“main”函数的外部引用,因此它不会编译。 |
|
|
3
3
一般来说,应用程序需要一个入口点,并且
|
|
|
4
3
从C++标准的角度来看,是的,它仍然是必需的。但我怀疑你的问题与此不同。 我认为你想的那样做会引起太多的问题。
例如,在许多环境中
但是,您仍然会遇到未定义全局构造函数的执行顺序的问题。这意味着在全局对象的任何特定构造函数中,您将无法对是否存在任何其他全局对象做出任何假设。 你可以试着解决构造器顺序问题,只要说每个构造器都有自己的线程,如果你想访问任何其他的全局对象,你就必须等待一个条件变量,直到它们说它们已经构造好。不过,这只是要求出现死锁,而这些死锁将很难调试。您还可以知道哪个线程退出程序的“返回值”将构成整个程序的实际返回值。
如果你想摆脱这两个问题
我想不出一种语言没有
|
|
|
5
2
如果正在构造多个全局对象,则无法保证哪个构造函数将首先运行。 |
|
6
2
如果您正在构建静态或动态库代码,则不需要定义
|
|
|
7
2
如果您是为windows编写代码,请执行 不 做这个。 完全从全局对象的构造函数中运行应用程序可能会很好地运行一段时间,但迟早你会调用错误的函数,最终导致程序在没有警告的情况下终止。
将整个应用程序编译成一个可执行文件并不能帮你省钱——许多Win32调用都有可能悄悄加载系统dll。 |
|
|
8
0
在有些实现中,全局对象是不可能的,或者对于此类对象不可能使用非平凡的构造函数(特别是在移动和嵌入式领域)。 |
|
AstralHex · 矩阵乘法代码工作不正常 1 年前 |
|
|
Fishie · 作为类成员的智能指针是否仍然自动释放?[关闭] 1 年前 |
|
|
Die4Toast · 递归调用成员箭头运算符-> 1 年前 |
|
|
Anka Hanım · 关于结构和动态数组地址的问题 1 年前 |