C++ 有没有办法开信用证+;程序可能在main()之前崩溃?

C++ 有没有办法开信用证+;程序可能在main()之前崩溃?,c++,c,function,crash,C++,C,Function,Crash,如果操作系统或运行时代码中有错误,程序在main()之前会崩溃吗?当然。C++对这种行为特别臭名昭著,但在C. < p>中仍然可以发生。如果你有C++程序,它可以在输入main函数之前通过函数和构造函数初始化变量和对象。其中任何一个错误都可能导致程序崩溃 我不确定,但如果您有这样一个全局变量: static SomeClass object; int main(){ return 0; } “主体类”构造器在执行前可能会崩溃程序。C++中的 < P>带有构造函数的静态对象将在主对象死亡

如果操作系统或运行时代码中有错误,程序在main()之前会崩溃吗?

当然。C++对这种行为特别臭名昭著,但在C.

< p>中仍然可以发生。如果你有C++程序,它可以在输入main函数之前通过函数和构造函数初始化变量和对象。其中任何一个错误都可能导致程序崩溃

我不确定,但如果您有这样一个全局变量:

static SomeClass object;

int main(){
   return 0;
}

“主体类”构造器在执行前可能会崩溃程序。C++中的

< P>带有构造函数的静态对象将在主对象死亡之前被调用

对c不确定

这是样品

class X
{
public:
X()
{
  char *x = 0;
  *x = 1;
}
};

X x;
int main()
{
return 0;
}

这将在主

是之前崩溃,至少在Windows下是这样。如果程序使用DLL,则可以在
main()
启动之前加载DLL。这些DLL的
DllMain
功能将在
main()
之前执行。如果遇到错误,则会导致整个进程停止或崩溃。C++程序中的全局和静态对象将在执行主语句前的第一个语句之前调用它们的构造函数,因此其中一个构造函数中的错误可能导致崩溃。 但是,这在C程序中是不会发生的。

有点:

如果在没有标准库的情况下编译,如下所示: gcc-nostlib-o你好你好.c


它将不知道如何运行main(),并将崩溃。

使用gcc,您可以用标记函数(这将导致函数在
main
之前运行)。在以下函数中,
premain
将在
main
之前调用:

#include <stdio.h>

void premain() __attribute__ ((constructor));

void premain()
{
    fputs("premain\n", stdout);
}

int main()
{
    fputs("main\n", stdout);
    return 0;
}
#include <iostream>

class Useless {
public:
    Useless() { throw "You can't construct me!"; }

};

static Useless object;

int main() {
    std::cout << "This will never be printed" << std::endl;

    return 0;
}
#包括
void premain()_属性__((构造函数));
无效
{
fputs(“premain\n”,标准输出);
}
int main()
{
fputs(“主\n”,标准输出);
返回0;
}

因此,如果在
premain
中有一个崩溃错误,那么在
main
之前就会崩溃,这取决于“在main之前”是什么意思,但是如果你的意思是“在main中的任何代码实际执行之前”,那么我可以想到一个例子:如果你在main中声明一个大数组作为局部变量,而这个数组的大小超过了可用的堆栈空间,那么在第一行代码执行之前,main的入口可能会出现
堆栈溢出。在嵌入式世界中,经常有许多事情在
main()
之前运行,这主要与平台设置有关,可能会出错。(或者,如果您在常规操作系统上使用的是一个时髦的链接器脚本,那么所有的赌注都是无效的,但我想这是非常罕见的。)

任何依赖于在main之前加载共享对象(DLL)的程序都可能在main之前失败

在Linux下,运行动态链接器库(ld-*.so)中的代码,以在main之前提供任何库依赖性。如果找不到任何需要的库、具有不允许您访问它们的权限、不是普通文件,或者没有链接程序的动态链接器在链接程序时认为应该具有的符号,则这可能会导致失败

此外,每个库在链接时都可以运行一些代码。这主要是因为库可能需要链接更多的库,或者可能需要运行一些构造函数(即使在C程序中,库可以有一些C++或其他使用SCORROCHOR)。 此外,标准C程序已经创建了stdio文件stdin、stdout和stderr。在许多系统上,这些也可以关闭。这意味着它们也是free()ed,这意味着它们(及其缓冲区)是malloc()ed,这可能会失败。它还表明,他们可能对这些文件结构所表示的文件描述符做了一些其他工作,这可能会失败

其他可能发生的事情是,如果操作系统在设置传递给程序的环境变量和/或命令行参数时出错。在调用main之前,main之前的代码可能已经对这些数据做了一些修改


很多事情都发生在主食之前。它们中的任何一个都可能以致命的方式失败

> P >一些平台抽象库重写(我个人只知道像Qt或ACE这样的C++库,但这可能是一些C库做了类似的事情)“Mead”,这样它们就指定了一个特定于平台的主类,比如<代码> int WINAPI WINMANT(HStuttHeStase,HSPuff-HPvStase,LpSTR LPCMDLINE,INTMCMDSFET);
并设置一些库文件,将命令行args转换为普通的
int-argc,char*argv[]
,然后调用普通的
int-main(int-argc,char*argv[])

当然,如果这些库没有正确实现这一点,它们可能会导致崩溃(可能是命令行参数格式错误的原因)


对于那些不知道这一点的人来说,这可能看起来像是在
main

之前的崩溃,一个有点做作的例子是:

int a = 1;
int b = 0;
int c = a / b;

int main()
{
    return 0;
}

你不太可能会做这样的事情,但如果你正在做大量的宏魔术,这是完全可能的。

有很多可能性

首先,我们需要了解在执行main之前实际发生了什么:

  • 动态库的加载
  • 全局变量的初始化
  • 在某些编译器中,某些函数可以显式执行
现在,任何一种情况都可能以多种方式导致崩溃:

  • 通常未定义的行为(取消引用空指针,访问不应访问的内存…)
  • 由于没有
    捕获
    ,因此引发异常>,调用
    终止
    ,程序结束
当然,这真的很烦人,而且可能很难调试,这就是为什么您应该尽量避免在
main
之前执行代码,如果可以的话,更喜欢延迟初始化,或者使用
#include <iostream>

class Useless {
public:
    Useless() { throw "You can't construct me!"; }

};

static Useless object;

int main() {
    std::cout << "This will never be printed" << std::endl;

    return 0;
}
int main() {
    char volatile stackoverflow[1000000000] = {0};
    return 0;
}