这个“CRT未初始化”错误是什么意思?

4

我在Visual Studio 2012 Express(当然是桌面版本)中创建了一个空的C++项目,并添加了一些随机的基本代码:

#include <cstdio>
#include <cstdlib>

typedef struct examplestruct
{
    unsigned char num1;
    unsigned short num2;
    unsigned long num3;
    unsigned long long num4;
} EXAMPLESTRUCT;

void examplefunction(unsigned long *num, int num2)
{
    *num += num2;
    return;
}

int main(int nArgs, char **pszArgs)
{
    EXAMPLESTRUCT ExStructInstance = {0xFF, 0xFFFF, 0xFFFFFFFF, 0xFFFFFFFFFFFFFFFF};
    printf("%d, %d, %u, %ull\n", ExStructInstance.num1, ExStructInstance.num2, ExStructInstance.num3, ExStructInstance.num4);
    unsigned long num5 = ExStructInstance.num1 + ExStructInstance.num2;
    printf("%d\n", num5);
    examplefunction(&num5, 10);
    printf("%d\n", num5);
    system("pause");
    return 0;
}

如果你对这是怎么回事感到困惑,我正在反汇编已创建的可执行文件以观察优化编译器的行为,并学习更多有关x86汇编的知识。
在项目设置中的链接器下,我选择了Multi-threaded (/MT)运行时库,以便进行静态链接。
我使用F5编译并开始调试,立即收到一个消息框中的错误提示:
运行时错误! 程序:C:\Users\xxxxx\Documents\P... R6030 CRT未初始化
因此,由于某个与运行时库有关的问题,这个基本程序无法运行,但我无法找出原因!
有什么想法吗?我只是想知道这里发生了什么。提前感谢!
编辑:FYI,所有操作都是在发布模式下完成的。

你说你已经编译并开始调试,但你也说你在发布模式下工作。你确定这两点吗? - alestanis
1
@alestanis 可以调试发布版本,只要编译时打开了调试信息;即使没有打开,你仍然可以附加调试器,在汇编中进行调试。 - stijn
@stijn 是的,调试信息已经打开了,而且我只是为了快速运行程序才这样做的。 - Archimaredes
当消息框出现时,您可以停止调试器吗? - Maximus
1
你写道:“立即在消息框中收到此错误”。我不确定在2012工作室中是否完全正确,但我认为你正在尝试创建控制台应用程序,但链接器认为这是GUI。 - Maximus
显示剩余3条评论
2个回答

2
使用“空项目”模板开始新项目可能会引起麻烦。您可能更改了其他项目设置,导致程序从main()方法而不是正常的入口点CRT启动函数开始运行。该函数初始化CRT,然后调用main()函数。很难猜测您是如何做到的,特别是当您谈论更改链接器设置以获取/MT时。这是一个编译器设置。
使用Win32 + Win2控制台应用程序项目模板可以轻松地避免这种情况。删除预生成的代码,但保留顶部的#include <stdafx.h>行。至少,您现在将拥有一个起点,可以帮助我们帮助您解决问题。不要跳过“Hello world”程序。

看起来我比你先回答了(似乎早了大约10秒)!另外,我的意思是/MT作为编译器设置,我犯了个错误。 - Archimaredes
谢谢你本来将是我的解决方案,不过!:D - Archimaredes

1

我解决了问题,这是我的错误。

我在链接器设置中明确设置了入口点为main,但实际上应该保持默认设置。

使用CRT的控制台程序实际上有一个名为_mainCRTStartup的入口点,在调用程序的main函数之前初始化CRT,这几乎是一个“伪入口点”。

如果您在链接器设置中自己设置入口点,则不会调用_mainCRTStartup,因此CRT不会被初始化;程序从main开始运行,无法执行CRT函数。

我只需删除明确定义的入口点,一切都正常了。

每天都会学到新东西。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接