#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++语言完全兼容的 ...
随机推荐
- 用GPU来运行Python代码
简介 前几天捣鼓了一下Ubuntu,正是想用一下我旧电脑上的N卡,可以用GPU来跑代码,体验一下多核的快乐. 还好我这破电脑也是支持Cuda的: $ sudo lshw -C display *-di ...
- 10月11日内容总结——global和nonlocal方法、函数名的多种用法、闭包函数和装饰器
目录 一.global和nonlocal方法 global方法 nonlocal方法 二.函数名的多种用法 1.函数名可以当作变量名赋值 2.函数名可以当作函数的参数 3.函数名可以当作函数的返回值 ...
- JSP第一次作业
1.环境搭建,运行出来一个JSP页面,显式hello <%@ page language="java" import="java.util.*" page ...
- Timer的定时调度函数schedule的四种用法
schedule的四种用法 schedule(task,time) task-所安排的任务 time-执行任务的时间 作用:在时间等于或者超过time的时候执行且仅执行一次 import java. ...
- Grafana 系列文章(十五):Exemplars
Exemplars 简介 Exemplar 是用一个特定的 trace,代表在给定时间间隔内的度量.Metrics 擅长给你一个系统的综合视图,而 traces 给你一个单一请求的细粒度视图:Exem ...
- spring-in-action-day05-REST
1.创建RESTFUL端点 (1)创建get端点 (2)创建post端点 (3)创建put/patch端点 (4)创建delete端点 2.启用超媒体 3.消费REST端点 3.1使用RestTemp ...
- 元数据库 information_schema.tables
转 https://www.cnblogs.com/ssslinppp/p/6178636.html 1.information_schema数据库 对于mysql和Infobright等数据库,i ...
- spring cloud alibaba - Nacos 下载安装
1.关于名字 前四个字母分别为Naming和Configuration的前两个字母,最后的s为Service 2.是什么 一个更易于构建云原生应用的动态服务发现,配置管理和服务管理中心.是注册中心和配 ...
- IoT 边缘集群基于 Kubernetes Events 的告警通知实现(二):进一步配置
上一篇文章 IoT 边缘集群基于 Kubernetes Events 的告警通知实现 目标 告警恢复通知 - 经过评估无法实现 原因: 告警和恢复是单独完全不相关的事件, 告警是 Warning 级别 ...
- mac os黑苹果安装
前言 习惯了mac敲代码的攻城师很难再去适应windows,那么如何在windows上安装苹果系统呢?用黑苹果. 关于黑苹果的安装,网上的一大堆教程显得过于啰嗦,又是安装Unlocker破解mac限制 ...