C++:程序在mian函数执行前后做了哪些工作?

在main执行之前,初始化系统相关资源:

  • 操作系统会初始化栈指针,指向栈的起始位置。
  • 初始化静态变量和全局变量,即.data段的内容。
  • 将未初始化的全局变量(int、bool、指针...)都赋初值为0,即.bss段的内容。
  • 初始化全局对象、静态对象,在main之前调用构造函数,这些代码会先执行。
  • __attribute__((constructor))特性,在函数前加上,即可在main函数之前执行这个函数。
  • 将main函数的参数argc、argv、envp传递给main函数,然后才真正运行main函数。

在main函数之后,会进行一些清理工作:

  • 调用全局对象、静态对象的析构函数。
  • 操作系统资源回收:当程序正常终止时,操作系统会回收分配给该程序的资源,如内存空间、打开的文件、网络连接等
  • __attribute__((destructor))特性,在函数前加上,即可在main函数之后执行这个函数。
  • 可以用atexit注册一个函数,它会在main函数之后执行。

关于attribute特性和atexit:

#include

using namespace std;

__attribute__((constructor)) void before_main()
{
	cout << __FUNCTION__ << endl;
}

__attribute__((destructor)) void after_main()
{
	cout << __FUNCTION__ << endl;
}


void fun()
{
	cout << __FUNCTION__ << endl;
}

int main()
{
	cout << __FUNCTION__ << endl;

	atexit(fun);
	return 0;
}

  • attribute这个特性是GCC和Clang编译器的扩展,不是C++标准的一部分,比如VS的编译器MSVC就不支持这个特性。
  • atexit是一个C标准库函数,用于在程序退出时注册一个函数,以便在程序终止前执行特定的清理操作。

关于main函数的参数:

在标准的C++中,main函数只有两种参数形式:无参数和带两个参数。

按照C++标准规定,main函数可以有两个参数:

int main(int argc, char* argv[])
  • argc 表示命令行参数的数量,包括程序名称本身。
  • argv 是一个char*的指针数组,每个元素指向一个命令行参数(以空格划分)

这是最常见的用法,并且在大多数C++编译器中都得到支持。

然而,根据C标准(ISO/IEC 9899:2018)的允许,main函数还可以具有另一种形式:

int main(int argc, char* argv[], char* envp[])
  • envp 也是一个char*的指针数组,每个元素指向一个环境变量字符串。环境变量是操作系统提供给程序运行的一组键值对数据。

但需要注意的是,虽然某些编译器可能支持这种三个参数的形式,但它并不属于标准C++,因此代码依赖于该特性会导致与其他平台或编译器的不兼容性。

如果需要使用环境变量相关的功能,建议使用操作系统或库提供的特定接口来处理环境变量,而不是依赖于main函数的第三个参数。

你可能感兴趣的:(C/C++,c++,开发语言)