全局变量初始化时机测试(动态库,静态库,执行程序中)

2023-11-09 15:44

本文主要是介绍全局变量初始化时机测试(动态库,静态库,执行程序中),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

测试环境

linux 和 windows

测试结果

  1. 在主函数定义的全局变量程序执行就会初始化
  2. 在执行程序中其他cpp中定义的全局变量,没有头文件的话,全局变量不会初始化
  3. 在动态库中定义的全局变量独立的cpp不会初始化
  4. 在静态库中定义的全局变量不管有没有头文件都不会初始化

说明

动态库中的全局变量是指在动态库中定义的非静态变量,它们可以被动态库中的其他函数或者加载动态库的程序访问。动态库中的全局变量什么时候初始化,取决于动态库的加载方式和操作系统的实现。

如果动态库是静态加载的,也就是在编译链接时就确定了动态库的位置和符号,那么动态库中的全局变量会在程序启动时就初始化,和静态库中的全局变量一样。这种方式的优点是加载速度快,缺点是占用内存空间和不利于更新。

如果动态库是动态加载的,也就是在程序运行时才根据需要加载动态库,那么动态库中的全局变量会在加载动态库时初始化,和动态库中的静态变量一样。这种方式的优点是节省内存空间和方便更新,缺点是加载速度慢,而且需要程序员手动管理动态库的加载和卸载。

不同的操作系统可能有不同的实现细节,比如在Linux中,动态库中的全局变量会在_init函数中初始化,而在Windows中,动态库中的全局变量会在DllMain函数中初始化。具体的初始化顺序也可能有所不同,一般来说,会按照变量的定义顺序进行初始化,但是如果有依赖关系,可能会有先后调整。

本地头文件

#ifndef _DYNAMIC_OUTTER_H_
#define _DYNAMIC_OUTTER_H_#include <iostream>#ifdef _WIN32
#if !defined(__PRETTY_FUNCTION__)
#define __PRETTY_FUNCTION__ __FUNCSIG__
#endif
#endifnamespace dymi{class DynamicOutter{public:DynamicOutter(){std::cout << __PRETTY_FUNCTION__ << std::endl;}void Display();}; 
}#endif //_DYNAMIC_OUTTER_H_

本地cpp文件

#include <iostream>#include "dynamicoutter.hh"namespace dymi{void DynamicOutter::Display(){std::cout << __PRETTY_FUNCTION__ << std::endl;}DynamicOutter outter;
}

主程序测试

#include <iostream>
#include <anotherpp.hh>#ifdef _WIN32
#if !defined(__PRETTY_FUNCTION__)
#define __PRETTY_FUNCTION__ __FUNCSIG__
#endif
#endifusing namespace dym;class StaticInner{public:StaticInner(){std::cout << __PRETTY_FUNCTION__ << std::endl;}
};StaticInner inner;int main(int argc, char* argv[])
{// dlib.Display();// dym::DynamicLib dli;// dli.Display();dym::UweMe ume;ume.Display();std::cout << __PRETTY_FUNCTION__ << std::endl;return 0;
}

结论

  • 动态库是静态加载还是动态加载。静态加载是在编译链接时就确定了动态库的位置和符号,动态加载是在程序运行时才根据需要加载动态库¹。
  • 动态库中的全局变量是在全局作用域还是在命名空间内定义的。在全局作用域定义的全局变量会在动态库加载时初始化,而在命名空间内定义的全局变量会在第一次使用时初始化²。
  • 动态库中的全局变量是否有构造函数和析构函数。如果有,那么它们的执行顺序可能会受到编译器和操作系统的影响³。

因此,如果您想确保动态库中的全局变量在正确的时机初始化,您可以考虑以下几个建议:

  • 尽量避免在动态库中使用全局变量,或者使用静态局部变量代替⁴。
  • 尽量使用简单类型的全局变量,或者使用懒汉式单例模式来封装复杂类型的全局变量。
  • 尽量使用动态加载的方式来加载动态库,或者使用显式调用的方式来获取动态库中的符号。

源码分享

dynamic

这篇关于全局变量初始化时机测试(动态库,静态库,执行程序中)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/377056

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

性能测试介绍

性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

字节面试 | 如何测试RocketMQ、RocketMQ?

字节面试:RocketMQ是怎么测试的呢? 答: 首先保证消息的消费正确、设计逆向用例,在验证消息内容为空等情况时的消费正确性; 推送大批量MQ,通过Admin控制台查看MQ消费的情况,是否出现消费假死、TPS是否正常等等问题。(上述都是临场发挥,但是RocketMQ真正的测试点,还真的需要探讨) 01 先了解RocketMQ 作为测试也是要简单了解RocketMQ。简单来说,就是一个分

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

动态规划---打家劫舍

题目: 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。 思路: 动态规划五部曲: 1.确定dp数组及含义 dp数组是一维数组,dp[i]代表

【测试】输入正确用户名和密码,点击登录没有响应的可能性原因

目录 一、前端问题 1. 界面交互问题 2. 输入数据校验问题 二、网络问题 1. 网络连接中断 2. 代理设置问题 三、后端问题 1. 服务器故障 2. 数据库问题 3. 权限问题: 四、其他问题 1. 缓存问题 2. 第三方服务问题 3. 配置问题 一、前端问题 1. 界面交互问题 登录按钮的点击事件未正确绑定,导致点击后无法触发登录操作。 页面可能存在

业务中14个需要进行A/B测试的时刻[信息图]

在本指南中,我们将全面了解有关 A/B测试 的所有内容。 我们将介绍不同类型的A/B测试,如何有效地规划和启动测试,如何评估测试是否成功,您应该关注哪些指标,多年来我们发现的常见错误等等。 什么是A/B测试? A/B测试(有时称为“分割测试”)是一种实验类型,其中您创建两种或多种内容变体——如登录页面、电子邮件或广告——并将它们显示给不同的受众群体,以查看哪一种效果最好。 本质上,A/B测

代码随想录冲冲冲 Day39 动态规划Part7

198. 打家劫舍 dp数组的意义是在第i位的时候偷的最大钱数是多少 如果nums的size为0 总价值当然就是0 如果nums的size为1 总价值是nums[0] 遍历顺序就是从小到大遍历 之后是递推公式 对于dp[i]的最大价值来说有两种可能 1.偷第i个 那么最大价值就是dp[i-2]+nums[i] 2.不偷第i个 那么价值就是dp[i-1] 之后取这两个的最大值就是d

c++的初始化列表与const成员

初始化列表与const成员 const成员 使用const修饰的类、结构、联合的成员变量,在类对象创建完成前一定要初始化。 不能在构造函数中初始化const成员,因为执行构造函数时,类对象已经创建完成,只有类对象创建完成才能调用成员函数,构造函数虽然特殊但也是成员函数。 在定义const成员时进行初始化,该语法只有在C11语法标准下才支持。 初始化列表 在构造函数小括号后面,主要用于给