#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++语言完全兼容的 ...
随机推荐
- My First Blog Ever——记我在交大ACM班的第一个学期
很巧的是,就在俞老师下发"学期小结"这一任务的前一天,我在跟朋友聊天时想到了要将自己这一学期的经历以文字的形式留存.毕竟,过去的一个学期实在有太多东西值得记述了:我离开了自己从童年 ...
- avue入门
<html> <head> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.min. ...
- 数据库系列:MySQL慢查询分析和性能优化
1 背景 我们的业务服务随着功能规模扩大,用户量扩增,流量的不断的增长,经常会遇到一个问题,就是数据存储服务响应变慢. 导致数据库服务变慢的诱因很多,而RD最重要的工作之一就是找到问题并解决问题. 下 ...
- http八股 跨域的本质 请求行 请求头 请求体 xss
1小八股 介绍 http 请求分为三个部分,请求行,请求头,请求体 还有状态码的含义 https://juejin.cn/post/7096317903200321544 2tips Content- ...
- 面向对象程序设计(三):new&deleet什么是动态内存
<C++ primer>中提到:在C++中,动态内存的管理是通过一对运算符来完成的: new 在内存池中为对象分配一块空间,并指向这个对象的指针,我们可以在这里对对象进行初始化: dele ...
- SpringBoot Test Junit 联用
需要导入SpringBoot test和junit的包 @RunWith(SpringRunner.class) @SpringBootTest(classes = PiYuApplication.c ...
- Solon2 开发之插件,二、插件扩展机制(Spi)
插件扩展机制,是基于 "插件" + "配置申明" 实现的解耦的扩展机制(类似 Spring Factories.Java Spi):简单.弹性.自由.它的核心作 ...
- python3中,len()、isalpha()、isspace()、isdigit()、isalnum()实例
# 实例:使用while循环 import string s1 = input('请输入一个字符串:\n') letters = 0 space = 0 digit = 0 others = 0 i ...
- 为什么sleeping的会话会造成阻塞(2)
背景 客户反馈系统突然从11:10开始运行非常缓慢,在SQL专家云中看到大量的产生阻塞的活动会话,KILL掉阻塞的源头马上又出现新的源头,实在没有办法只能重启应用程序断开所有数据库连接才解决,请我们协 ...
- 关于vue项目和内嵌iframe页面之间的通信问题
最近项目中遇到一个与内嵌iframe页面之间通信的问题,起初与原生之间通信很简单,没想到过与vue项目通信的问题,霎时间一脸懵*啊,百度了一下,原来是那么简单,这里记录下以供下次参考 //vue页面 ...