C++全局构造和初始化
片段摘自程序员的自我修养—链接、装载与库.pdf 11.4
程序在进入main之前,需要对全局对象进行构造初始化。
glibc全局对象进行构造初始化
gibc启动程序时会经过.init段,退出程序时会经过.finit段。这两个段中的代码最终拼接成_init()和_finit(),这两个函数优先于/后于main函数执行。
_start->_init()->main()->_finit()
用户所有放在.init段的代码将在main函数之前执行,即全局对象的初始化。具体执行流程如下:
_start->__libc_start_main->__libc_csu_init->_init->__do_global_ctors_auxvoid __do_global_ctors_aux(void)
{/*call constructor functions*/unsigned long nptrs = (unsigned long)__CTOR_LIST__[0];
for(unsigned i = nptrs;i >= 1;i--)__CTOR_LIST__[i]
}
CTOR_LIST 存放所有全局对象的构造和初始化的函数指针。__do_global_ctors_aux从__CTOR_LIST__ 的下一个位置开始,按顺序执行函数指针,直到遇上NULL(__CTOR_END__),从而调用所有全局对象的构造函数。
那么__CTOR_LIST__ 是如何初始化的呢?
GCC编译器在编译的时候会遍历每个编译单元的全局对象,生成一个特殊函数_GLOBAL__I_HW,利用这个特殊函数对本编译单元的所有全局、静态对象进行初始化。
static void _GLOBAL__I_HW(void)
{Hw::Hw();//构造对象atexit(__tcf_l)
}
一旦目标文件里面有这样的函数,编译器则会在这个编译单元目标文件的.ctors放置一个指针,指向_GLOBAL__I_HW。即__CTOR_LIST__列表保存的是每个编译单元的_GLOBAL__I_HW函数指针。链接器则会将所有的目标文件的.ctors合并成一个.ctors段
__CTOR_LIST__ 代表所有.ctors的起始地址。
__CTOR_END__ 指向.ctors段的末尾。

所以如果想在main之前调用函数,只需要在.ctors段里面添加函数指针即可。
#include <stdio.h>
#include <stdlib.h>//main函数之前执行
__attribute((constructor)) void before_main()
{printf("====%s=====\n", __FUNCTION__);
}//main函数之后执行
__attribute((destructor)) void after_main()
{printf("====%s=====\n", __FUNCTION__);
}int main(int argc, char **argv)
{printf("=====entering %s.========\n", __FUNCTION__);printf("====exiting from main!===\n");return 0;
}

MSVC 全局对象进行构造初始化
msvc的入口函数mainCRTStartup
mainCRTStartup()
{..._initterm(__xc_a,__xc_z);...
}
其中__xc_a和__xc_z是两个函数指针。而_initterm的内容则是:
typedef void (__cdecl *_PVFV)();
static void __cdecl _initterm(_PVFV* pfbegin,_PVFV* pfend)
{while(pfbegin < pfend){if(*pfbegin != null)(**pfbegin)();++pfbegin;}
}
第一眼看上去和glibc几乎一模一样,__xc_a相当于指针的开始地址__CTOR_LIST__,__xc_z则相当于结束地址__CTOR_END__
那么msvc 是如何初始化__xc_a和__xc_z的呢?
_CRTALLOC(".CRT$XCA") _PVFV __xc_a[] = {NULL};
_CRTALLOC(".CRT$XCZ") _PVFV __xc_Z[] = {NULL};
其中_CRTALLOC定义
#pragma section(".CRT$XCA",long,read)
#pragma section(".CRT$XCZ",long,read)#define _CRTALLOC(x) __declspec(allocate(x))
#pragma section("section-name",[,attributes])的作用是在obj的文件里创建名为section-name的段,并具有指定的attributes属性。所以上述两条指令实际生成了两个名为.CRT$XCA、.CRT$XCZ的段。__declspec(allocate(x)则表示变量将变量分配在段x里。所以__xc_a分配在.CRT$XCA、__xc_z分配在.CRT$XCZ里。
msvc编译的时候,会为每一个编译单元生成.CRT$XCU(U是User的意思)的段。在这个段里面加入自身的全局初始化函数。链接的时候将所有相同属性的段合并。段根据字母A-Z的顺序排序。

所以如果想在main之前调用函数,只需要在段(A-Z之间,不包含A,Z).CRT$XCB里面添加函数指针即可。
因为全局初始化函数在段
.CRT$XCU里面,根据A-Z排序并执行。所以如果想要在全局构造函数之前执行,段名必须在U之前。如果想在全局构造函数之后main之前则段名必须在U之后。不包含A,Z
class CA
{
public:CA(){printf("CA::CA\r\n");}~CA(){printf("CA::~CA\r\n");}
};#define SECNAME ".CRT$XCB"#pragma section(SECNAME,long,read)
void foo()
{printf("foo \r\n");
}
typedef void(_cdecl* _PVFV)();
_declspec(allocate(SECNAME)) _PVFV dummy[] = { foo };CA g_obj;
int main()
{printf("main enter\r\n");printf("main exit\r\n");return 0;
}
.CRT$XCB段输出(先执行foo,在执行全局对象初始化,在执行main)

.CRT$XCY段输出(先执行全局对象初始化,在执行foo,在执行main)

Note:注意事项,如果在main函数之前想引用全局变量或者函数,此时全局变量的构造函数还没执行。可能结果和预期不一致。
demo: foo里面改变CA成员变量的值。
CA g_obj;void foo()
{g_obj.m_a = 10;printf("foo g_obj addr:%I64d g_obj.m_a=%d\r\n", &g_obj, g_obj.m_a);
}int main()
{printf("main enter\r\n");printf("foo g_obj addr:%I64d g_obj.m_a=%d\r\n", &g_obj, g_obj.m_a);printf("main exit\r\n");return 0;
}

虽然在foo里面改变了m_a,但是稍后执行段.CRT$XCU时此时会调用CA::CA导致m_a被重新赋值0
相关文章:
C++全局构造和初始化
片段摘自程序员的自我修养—链接、装载与库.pdf 11.4 程序在进入main之前,需要对全局对象进行构造初始化。 glibc全局对象进行构造初始化 gibc启动程序时会经过.init段,退出程序时会经过.finit段。这两个段中的代码最终拼接成_init()和_finit(),这两个…...
安全见闻-泷羽sec课程笔记
编程语言 C语言:一种通用的、面向过程的编程语言,广泛应用于系统软件和嵌入式开发。 C:在C语言基础上发展而来,支持面向对象编程,常用于尊戏开发、高性能计算等领域。 Java:一种广泛使用的面问对象编程语言,具有跨平台…...
游戏引擎学习第17天
视频参考:https://www.bilibili.com/video/BV1LPUpYJEXE/ 回顾上一天的内容 1. 整体目标: 处理键盘输入:将键盘输入的处理逻辑从平台特定的代码中分离出来,放入更独立的函数中以便管理。优化消息循环:确保消息循环能够有效处理 …...
【FFmpeg】FFmpeg 内存结构 ③ ( AVPacket 函数简介 | av_packet_ref 函数 | av_packet_clone 函数 )
文章目录 一、av_packet_ref 函数1、函数原型2、函数源码分析3、函数使用代码示例 二、av_packet_clone 函数1、函数原型2、函数源码分析 FFmpeg 4.0 版本源码地址 : GitHub : https://github.com/FFmpeg/FFmpeg/tree/release/4.0GitCode : https://gitcode.com/gh_mirrors/ff…...
【学习笔记】量化概述
Quantize量化概念与技术细节 题外话,在七八年前,一些关于表征的研究,会去做表征的压缩,比如二进制嵌入这种事情,其实做得很简单,无非是找个阈值,然后将浮点数划归为零一值,现在的Qu…...
同步互斥相关习题10道 附详解
PV操作 2016 某系统允许最多10个进程同时读文件F,当同时读文件F的进程不满10个时,欲读该文件的其他文件可立即读,当已有10个进程在读文件F时读,其他欲读文件F的进程必须等待,直至有进程读完后退出方可去读 在实现管…...
【Python · PyTorch】卷积神经网络 CNN(LeNet-5网络)
【Python PyTorch】卷积神经网络 CNN(LeNet-5网络) 1. LeNet-5网络※ LeNet-5网络结构 2. 读取数据2.1 Torchvision读取数据2.2 MNIST & FashionMNIST 下载解包读取数据 2. Mnist※ 训练 LeNet5 预测分类 3. EMnist※ 训练 LeNet5 预测分类 4. Fash…...
Git 拉取指定分支创建项目
一 背景 因为项目过大,只需要部分分支的代码即可。 二 实现 方法一:使用 --single-branch 参数 git clone 支持只拉取指定分支,而不是整个库的所有分支: git clone --branch <branch_name> --single-branch <reposi…...
CF862B Mahmoud and Ehab and the bipartiteness(二分图的性质)
思路:一个二分图是由两个集合组成的,同一个集合中的节点间不能连边,所以一个二分图最多有cnt[1]*cnt[2]条边,题目给出一个树的n-1条边,要我们添加最多的边数使他成为二分图,添加的边数就是cnt[1]*cnt[2]-n1…...
React Native 全栈开发实战班 :数据管理与状态之React Hooks 基础
在 React Native 应用中,数据管理与状态管理是构建复杂用户界面的关键。React 提供了多种工具和模式来处理数据流和状态管理,包括 React Hooks、Context API 以及第三方状态管理库(如 Redux)。本章节将详细介绍 React Hooks 的基础…...
传奇996_22——自动挂机
登录钩子函数中执行 callscript(actor, "../QuestDiary/主界面基础按钮/主界面基础按钮QM", "基础按钮QM")基础按钮QM执行了已下代码 #IF Equal <$CLIENTFLAG> 1 #ACT goto PC端面板加载#IF Equal <$CLIENTFLAG> 2 #ACT goto 移动端面板加载…...
faiss 提供了多种索引类型
faiss 多种索引类型 在 faiss 中,IndexFlatL2 是一个简单的基于 L2 距离(欧几里得距离)进行索引的索引类型,但实际上,faiss 提供了多种索引类型,支持不同的度量方式和性能优化,您可以根据需求选…...
比rsync更强大的文件同步工具rclone
背景 多个复制,拷贝,同步文件场景,最大规模的是每次几千万规模的小文件需要从云上对象存储中拉取到本地。其他的诸如定期数据备份,单次性数据备份。 rsync是单线程的,开源的mrsync是多线程的,但适用范围没…...
《业务流程--穿越从概念到实践的丛林》读后感一:什么是业务流程
1.1 流程和业务流程概念辨析 业务流程建模标准(BPMN)对于业务流程的定义:一个业务流程由为了配合一个组织性或技术环境而一系列活动组成。这些活动共同实现一个业务目标。 业务流程再造最有名的倡导者托马斯.H.达文波特对于流程和业务流程的定义:流程是一组结构化且可度量的…...
解决docker mysql命令行无法输入中文
docker启动时,设置支持中文 docker run --name mysql-container -e MYSQL_ROOT_PASSWORDroot -d mysql:5.7 --character-set-serverutf8mb4 --collation-serverutf8mb4_unicode_ci --default-time-zone8:00 进入docker时,指定LANG即可 docker exec -it …...
基于Java Springboot城市公交运营管理系统
一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术:Html、Css、Js、Vue、Element-ui 数据库:MySQL 后端技术:Java、Spring Boot、MyBatis 三、运行环境 开发工具:IDEA/eclipse 数据…...
Lc70--319.两个数组的交集(二分查找)---Java版
1.题目描述 2.思路 用集合求交集,因为集合里面的元素要满足不重复、无序、唯一。使得集合在去重、查找和集合操作(如交集、并集、差集等)中非常高效和方便。 3.代码实现 class Solution {public int[] intersection(int[] nums1, int[] nu…...
亿咖通科技应邀出席微软汽车行业智享会,分享ECARX AutoGPT全新实践
11月14日,全球出行科技企业亿咖通科技(纳斯达克股票代码:ECX)应邀于广州参加由微软举行的汽车行业智享会,揭晓了亿咖通科技对“AI定义汽车”时代的洞察与技术布局,分享了亿咖通科技汽车垂直领域大模型ECARX…...
Python教程:运算符重载
在Python中,运算符重载是通过定义特殊方法(也称为魔术方法)来实现的,这些特殊方法允许类的实例像内置类型那样使用运算符。 Python提供了一系列这样的特殊方法,用于重载各种运算符。 以下是一些常见的运算符重载特殊…...
AWTK VSCode 实时预览插件端口冲突的解决办法
AWTK XML UI 预览插件:在 vscode 中实时预览 AWTK XML UI 文件,在 Copilot 的帮助下,可以大幅提高界面的开发效率。 主要特色: 真实的 UI 效果。可以设置主题,方便查看在不同主题下界面的效果。可以设置语言…...
AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
