#pragma directive
#pragma package(smart_init)
#pragma package(smart_init)确保已打包的单元按照其依赖关系确定的顺序进行初始化(默认情况下包含在package(包)源文件中。)通常,您将#pragma package用于作为package(包)构建的.cpp文件。简而言之就是按照单元的依赖关系顺序进行初始化,一般用于构建Package(软件包)中
注意:不要在头文件中使用#pragma package(smart_init)。 这样做可能导致编译器错误。
该编译指令影响该编译单元的初始化顺序。 对于单元,初始化按以下顺序进行:
1)根据它们的“uses”依赖性,即,如果unitA依赖于unitB,则必须在unitA之前初始化unitB。
2)链接顺序。
3)单元(unit)内的优先级顺序。
对于常规目标文件(obj文件)(不是作为单元(unit)构建的目标文件),首先根据优先级顺序进行初始化,然后根据链接顺序进行初始化。 更改对象文件的链接顺序将更改全局对象构造函数的调用顺序。
以下示例显示了单元和常规目标文件之间的初始化有何不同。
假设您有三个源文件A,B和C,它们使用#pragma package(smart_init)“智能初始化”,并且具有优先级设置为10、20和30的函数(由#pragma startup的优先级参数定义)。这些函数是根据其优先级值和父源文件命名的,因此名称分别为a10,a20,a30,b10,b20等。这是三个程序A,B和C:
// A.cpp
#include <stdio.h> #ifdef USE_PACKAGE_INIT
#pragma package(smart_init)
#endif void A10() {
printf("%s() ", __FUNCTION__);
}
#pragma startup A10 10 void A20() {
printf("%s() ", __FUNCTION__);
}
#pragma startup A20 20 void A30() {
printf("%s() ", __FUNCTION__);
}
#pragma startup A30 30
// B.cpp
#include <stdio.h> #ifdef USE_PACKAGE_INIT
#pragma package(smart_init)
#endif void B10() {
printf("%s() ", __FUNCTION__);
}
#pragma startup B10 10 void B20() {
printf("%s() ", __FUNCTION__);
}
#pragma startup B20 20 void B30() {
printf("%s() ", __FUNCTION__);
}
#pragma startup B30 30
// C.cpp
#include <stdio.h> #ifdef USE_PACKAGE_INIT
#pragma package(smart_init)
#endif void C10() {
printf("%s() ", __FUNCTION__);
}
#pragma startup C10 10 void C20() {
printf("%s() ", __FUNCTION__);
}
#pragma startup C20 20 void C30() {
printf("%s() ", __FUNCTION__);
}
#pragma startup C30 30
如果按编写的方式并定义了USE_PACKAGE_INIT来构建源文件,则会打印出以下内容:
> A10() A20() A30() B10() B20() B30() C10() C20() C30()
也就是说,优先级被忽略,每个单元一次运行其所有初始化。
如果您在未定义USE_PACKAGE_INIT的情况下构建源文件,则会得到完全不同的结果。 在这种情况下,运行程序时,将输出以下内容:
> A10() B10() C10() A20() B20() C20() A30() B30() C30()
也就是说,使用 startup优先级顺序。
由于这三个都是单元,并且如果A uses B和C,并且链接顺序是A,B,C,则初始化的顺序是:
> B10()B20()B30()C10()C20()C30() A10()A20()A30()
如果以上是目标文件,而不是单元,则顺序为:
> A10()B10()C10()A20()B20()C20()A30()B30()C30()
使用#pragma package(smart_init)的.cpp文件还要求从任意声明#pragma pragma(smart_init)的.cpp文件中到其他目标文件的任何#pragma link引用都必须由一个单元解析。仍然可以通过库解析对非对象文件的#pragma link引用,依此类推。
#pragma package(smart_init, weak)
#pragma package(smart_init,weak)指令会影响对象文件在包的.bpi和.bpl文件中的存储方式。 如果#pragma package(smart_init,weak)出现在单元文件中,则编译器将在可能的情况下从BPL中忽略该单元,并在另一个应用程序或程序包需要时创建该单元的未打包的本地副本。 使用此伪指令编译的单元被称为“弱包装”。
#pragma package(smart_init,weak)用于消除可能依赖于同一外部库的程序包之间的冲突。
包含#pragma package(smart_init,weak)指令的单元文件不得具有全局变量。
#pragma link
语法:
#pragma link "[path]modulename[.ext]"
#pragma link指令指示链接程序将指定文件链接到可执行文件中。
使用path参数指定目录。 缺省情况下,链接器在本地目录和链接器的-L选项指定的任何路径中搜索模块名称。
只要您使用默认文件类型,就不要指定modulename的文件扩展名(.ext)。 链接器为modulename的文件扩展名(.ext)假定以下默认值:
.obj
extension for BCC32.o
extension for Clang-enhanced C++ compilers
因此,如果省略.ext,则会根据您当前的目标平台自动使用正确的扩展名。
#pragma directive的更多相关文章
- #pragma Directive in C/C++
The #pragma is complier specified. for example, the code below does not work in gcc. #pragma startup ...
- 重新梳理HTML基础知识
缘起 HTML(HyperText Markup Language超文本标记语言)是用于构建web页面的标记语言和通用标准.它并不是一项新的发明,因为超文本(具有超链接的文本)和标记语言(用于电子文档 ...
- C中的预编译宏定义
可以用宏判断是否为ARC环境 #if _has_feature(objc_arc) #else //MRC #endif C中的预编译宏定义 -- 作者: infobillows 来源:网络 在将一 ...
- How do I place a group of functions or variables in a specific section?
http://supp.iar.com/Support/?Note=27498 EWARM v5.xx (and newer) The placement of a few functions in ...
- RFC 2616
Network Working Group R. Fielding Request for Comments: 2616 UC Irvine Obsoletes: 2068 J. Gettys Cat ...
- 基于NodeJs的网页爬虫的构建(一)
好久没写博客了,这段时间已经忙成狗,半年时间就这么没了,必须得做一下总结否则白忙.接下去可能会有一系列的总结,都是关于定向爬虫(干了好几个月后才知道这个名词)的构建方法,实现平台是Node.JS. 背 ...
- scanf()常犯错误
------------------------------------------------------------------------ <> 本意:接收字符串. 写成代码:voi ...
- RFC2616-HTTP1.1-Header Field Definitions(头字段规定部分—单词注释版)
part of Hypertext Transfer Protocol -- HTTP/1.1RFC 2616 Fielding, et al. 14 Header Field Definitions ...
- HTML5 Differences from HTML4
Abstract "HTML5 Differences from HTML4" describes the differences of the HTML5 specificati ...
- C预编译, 预处理, C/C++头文件, 编译控制,
在所有的预处理指令中,#Pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作.#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的 ...
随机推荐
- you-get下载B站视频
you-get下载B站视频 库存 you-get介绍 https://github.com/soimort/you-get you-get是一个命令行工具,可以下载知名网站的视频 支持的网站有 ht ...
- 2211-22学习记录之python百分数,time模块
百分数 print(' {:.0%}'.format(84/100)) 输出为84% 以上百分数输出是使用到了字符串格式化函数format(),在其中将分数42/50作为值给传递了进去.如果将分子分母 ...
- js 全屏代码实现方法
1 /* 全屏方法 2 * ========= 3 <button class="roll-nav roll-right fullscreen"> 4 <i cl ...
- 解决 Vue3 中路由切换到其他页面再切换回来时 Echarts 图表不显示的问题
问题复现: 正常状态下: 切换到其他页面再切换回来: 问题解决: 其实这个问题的解决方式官网写得清清楚楚,我们看看官网怎么解决的: 接下来我用代码解释下这句话(正确的做法是,在图表容器被销毁之后,调用 ...
- 接口介绍以及postman的基本使用
集成测试--测试接口 接口测试也是在测试执行阶段做 一.什么是接口 软件的不同模块之间互相发送数据的一个通道 二.接口的组成 1.请求URL--接口地址2.请求类型 get get请求的参数是暴露在U ...
- 记录一次vue部署docker步骤
vue部署docker 拉取nginx镜像 docker pull nginx 有Dockerfile文件步骤: 1.打包vue npm run build 2.写一个default.conf 文件, ...
- 主流的第三方直播SDK对比(腾讯云、即构、阿里云、声网、网易云信、网宿)
直播业务概述 大家所熟知的直播平台虎牙.斗鱼.快手.抖音.B站,直播功能看似普遍,但从零到一开发却不简单.直播中运用到的技术难点非常之多,音频视频处理/编解码,前后处理,直播分发,即时通讯等技术,学好 ...
- 了解舵机以及MG996R的控制方法
了解舵机以及MG996R的控制方法 1.舵机基础知识: 舵机是遥控航空.航天模型控制动作,改变方向的重要组成部件,舵机是一种位置(角度)伺服的驱动器. 舵机主要适用于那些需要角度不断变化并可以保持的控 ...
- Eureka高可用集群服务端和客户端配置
微服务应用中,生产环境一般都需要保障服务注册中心的高可用!高可用也分好几个等级,例如:同数据中心(可用Zone区)高可用-->同地域(Region)跨数据中心(可用Zone区)高可用--> ...
- Activity 和 Fragment 中的视图绑定
开启视图绑定 找到 build.gradle 文件,因为有两个 build.gradle,我们要操作的是第二个: 在这个位置加上这一句话,然后点击右上角的 Sync Now 按钮更新项目: andro ...