快捷搜索:   服务器  安全  linux 安全  MYSQL  dedecms

linux:入口函数和程序初始化

    如果把一个程序比作一个世界,那么程序的启动无疑就是“创世”。在本章里,我们将从程序的创世开始,接触到在程序背后另一类默默服务的团体。它们能够使得程序正常地启动,能够使得各种我们熟悉的函数发挥作用,它们就是应用程序的运行库。

  11.1 入口函数和程序初始化

  11.1.1 程序从main开始吗

  正如基督徒认为世界的诞生起于7天创世一样,任何一个合格的C/C++程序员都应该知道一个事实:程序从main函数开始。但是事情的真相真是如此吗?如果你善于观察,就会发现当程序执行到main函数的第一行时,很多事情都已经完成了:

 

  从代码中我们可以看到,在程序刚刚执行到main的时候,全局变量的初始化过程已经结束了(a的值已经确定),main函数的两个参数(argc和argv)也被正确传了进来。此外,在你不知道的时候,堆和栈的初始化悄悄地完成了,一些系统I/O也被初始化了,因此可以放心地使用printf和malloc。

  
    在这里,对象v的构造函数,以及用于初始化全局变量g的函数foo都会在main之前调用。

  【铁证3】atexit也是一个特殊的函数。atexit接受一个函数指针作为参数,并保证在程序正常退出(指从main里返回或调用exit函数)时,这个函数指针指向的函数会被调用。例如:

  void foo(void)

  {

  printf("bye!\n");

  }

  int main()

  {

  atexit(&foo);

  printf("endof main\n");

  }

  用atexit函数注册的函数的调用时机是在main结束之后,因此这段代码的输出是:

  endof main

  bye!

  所有这些事实都在为“main创论”提供不利的证据:操作系统装载程序之后,首先运行的代码并不是main的第一行,而是某些别的代码,这些代码负责准备好main函数执行所需要的环境,并且负责调用main函数,这时候你才可以在main函数里放心大胆地写各种代码:申请内存、使用系统调用、触发异常、访问I/O。在main返回之后,它会记录main函数的返回值,调用atexit注册的函数,然后结束进程。

 [2] [3] [4] [5] [6] [7] [8] [9] [10]  ... 下一页  >> 

顶(0)
踩(0)

您可能还会对下面的文章感兴趣:

最新评论