• 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:

    1. #include
    2. using namespace std;
    3. __attribute__((constructor)) void before_main()
    4. {
    5. cout << __FUNCTION__ << endl;
    6. }
    7. __attribute__((destructor)) void after_main()
    8. {
    9. cout << __FUNCTION__ << endl;
    10. }
    11. void fun()
    12. {
    13. cout << __FUNCTION__ << endl;
    14. }
    15. int main()
    16. {
    17. cout << __FUNCTION__ << endl;
    18. atexit(fun);
    19. return 0;
    20. }
    • attribute这个特性是GCC和Clang编译器的扩展,不是C++标准的一部分,比如VS的编译器MSVC就不支持这个特性。
    • atexit是一个C标准库函数,用于在程序退出时注册一个函数,以便在程序终止前执行特定的清理操作。

    关于main函数的参数:

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

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

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

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

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

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

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

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

  • 相关阅读:
    kafka安装流程
    IPSec NAT穿越原理
    C++图解模板
    javascript的call、apply、bind的实现
    【数据结构】别跟我讲你不会冒泡排序
    unity---接入Admob
    网络编程中的重难点:套接字的应用和理解
    HTML CSS JS 网页设计作业「我的家乡吉林」
    PHP表单token验证防CSRF攻击
    configure生成的makefile中工具的版本,可以直接修改为自己使用的版本
  • 原文地址:https://blog.csdn.net/weixin_73567058/article/details/133977234