cmake进阶:变量的作用域说明三(从函数作用域方面)

 一.  简介

前一篇文章从函数作用域方面学习了 变量的作用域。文章如下:

cmake进阶:变量的作用域说明一(从函数作用域方面)-CSDN博客
cmake进阶:变量的作用域说明二(从函数作用域方面)-CSDN博客

本文继续从函数作用域方面学习了 变量的作用域。

二.  变量的作用域

1. 函数内如何设置外部定义的变量

那如果需要在函数内修改外部定义的变量,该如何做呢?

譬如下面这段代码:

# 函数 xyz
function(xyz)set(ABC "Hello China!")
endfunction()set(ABC "Hello World!")
xyz() # 调用函数message("${ABC}")

通过前面的介绍可知,xyz()函数内通过 set 只是创建了一个在函数内部使用的变量 ABC,而并非是去修改外部定义的变量 ABC,那如何能使得函数内可以去修改外部定义的变量呢?

其实也非常简单,set 命令提供了一个可选选项 PARENT_SCOPE,只需在调用 set 命令时在参数列表末尾加上 PARENT_SCOPE 关键字即可。如下所示:

# 函数 xyz
function(xyz)set(ABC "Hello China!" PARENT_SCOPE) #加上 PARENT_SCOPE
endfunction()set(ABC "Hello World!")
xyz() # 调用函数message("${ABC}")

将上面代码添加到 工程的顶层 CMakeLists.txt文件,进入 build目录下,执行 "cmake .."命令后打印如下信息:

打印信息证明,加上 PARENT_SCOPE 之后确实可以,那 PARENT_SCOPE 选项究竟是什么?

官方给出的解释是这样的:

如果添加了 PARENT_SCOPE 选项,则变量将设置在当前作用域范围之上 的作用域范围内,每个目录(在这里“目录”指的是包含了 CMakeLists.txt 的目录)或函数都会创建一个新作用域,此命令会将变量的值设置到父目录或上层调用函数中(函数嵌套的情况下)。

其实就是说,如果 set 命令添加了 PARENT_SCOPE 选项,那就意味着并不是在当前作用域(set 命令所在作用域)内设置这个变量,而是在当前作用域的上一层作用域(父作用域)中设置该变量;

三.  举例说明 “当前作用域的上一层作用域 ”

当前作用域的上一层作用域该怎么理解呢?
这个根据具体的情况而定,下面举几个例子进行说明。

1. 示例代码 1

示例代码如下:

# 函数 xyz
function(xyz)set(ABC "Hello China!" PARENT_SCOPE) #加上 PARENT_SCOPE
endfunction()set(ABC "Hello World!")
xyz() # 调用函数message("${ABC}")
在这个例子中,函数 xyz 中调用 set 时添加了 PARENT_SCOPE 选项,意味着会在函数 xyz 的上一层作 用域中设置 ABC 变量,函数的上一层作用域也就是调用 xyz() 函数时所在的作用域,也就是当前源码对应 的作用域(当前目录作用域)。

2. 示例代码 2

示例代码如下:

# 函数 func2
function(func2)set(ABC "Hello People!" PARENT_SCOPE)
endfunction()# 函数 func1
function(func1)set(ABC "Hello China!")func2()
endfunction()set(ABC "Hello World!")
func1()message("${ABC}")
在这个示例中,函数 func1 中调用了 func2 ,那么函数 func2 的上一层作用域就是 func1 函数对应的作用域。

3. 示例代码 3

有如下工程目录结构:

顶层 CMakeLists.txt 文件内容如下:
# CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project(TEST)add_subdirectory(src)
xyz()message("${ABC}")

顶层源码调用 src 目录下的子源码,子源码下定义了一个函数 xyz ,如下所示:

# src 下的 CMakeLists.txt
function(xyz)set(ABC "Hello World!" PARENT_SCOPE)
endfunction()

在这种情况下,函数 xyz 的上一层作用域便是顶层目录作用域(顶层源码作用域),关键是看“谁”调用该函数。

同理下面这种情况也是如此,顶层 CMakeLists.txt 文件:
# CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project(TEST)
add_subdirectory(src)
message("${ABC}")

src 目录下的 CMakeLists.txt 文件:
# src 下的 CMakeLists.txt
set(ABC "Hello World!" PARENT_SCOPE)
变量 ABC 会在顶层源码中被设置,而不是 set 命令所在的作用域中。
下一篇文章来学习 函数的返回值是如何实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/7316.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++:多继承虚继承

在C中,虚继承(Virtual Inheritance)是一种特殊的继承方式,用于解决菱形继承(Diamond Inheritance)问题。菱形继承指的是一个类同时继承自两个或更多个具有共同基类的类,从而导致了多个实例同一个…

Problem 5: Whack-A-Mole打地鼠

实战题:打地鼠 内容如附件所示: 测试数据为:1,2,4,8,9,10,11,14 答案为:10,2,4 原始分布: 击打10号 击打2号 击打4号 要求,所示实例解以图示的方式给出,并且5组测试数据都需要测试,…

Labels and Databases for Mac:强大的标签与数据库管理工具

Labels and Databases for Mac是一款集标签制作与数据库管理于一体的强大工具,专为Mac用户打造,旨在提供高效、便捷的标签制作与数据管理体验。 这款软件拥有丰富的内置标签格式,用户可轻松创建各种标签、信封和卡片,满足个性化需…

PopChar for Mac v10.1激活版:特殊字符输入工具

PopChar for Mac是一款专为Mac用户设计的字符输入工具,其简单直观的功能使得查找和插入特殊字符变得轻而易举。 PopChar for Mac v10.1激活版下载 首先,PopChar为Mac提供了访问所有字体字符的能力,包括那些难以通过键盘直接输入的字符。用户只…

STM32编译前置条件配置

本文基于stm32f104系列芯片,记录编程代码前需要的操作: 添加库文件 在ST官网下载标准库STM32F10x_StdPeriph_Lib_V3.5.0,解压后,得到以下界面 启动文件 进入Libraries,然后进入CMSIS,再进入CM3&#xff…

【DevOps】探索Linux命令行世界:深入了解Shell的力量

目录 一、Linux Shell 详细介绍 1. Shell基础概念 2. Shell的功能特性 3. 常用Shell命令与技巧 4. 高级Shell特性与实践 二、常见的Shell及其比较 1. Bash (Bourne Again SHell) 2. Zsh (Z Shell) 3. Fish (Friendly Interactive SHell) 4. Ksh (Korn SHell) 5. Csh …

青春送温暖 立夏寄真情

(通讯员:赵灿飞 图:杨美、孙红浪) 在青春洋溢的五月,为传承中华民族尊老敬老的传统美德,促进当代青年与老人的跨代交流,增强青年的社会责任感和使命感,传递正能量和关爱困难群体…

linux下sd卡的备份与还原

在Ubuntu上制作SD卡备份镜像,你可以使用dd命令。以下是一个基本的步骤和示例代码: 插入SD卡到电脑。确定SD卡设备路径,使用lsblk或sudo fdisk -l命令。确定备份镜像文件的路径。使用dd命令制作备份。 示例代码: bash# 查看连接的…

ubuntu 安装单节点HBase

下载HBase mkdir -p /home/ellis/HBase/ cd /home/ellis/HBase/ wget https://downloads.apache.org/hbase/2.5.8/hbase-2.5.8-bin.tar.gz tar -xvf hbase-2.5.8-bin.tar.gz安装java jdk sudo apt install openjdk-11-jdksudo vim /etc/profileexport JAVA_HOME/usr/lib/jvm/…

(delphi11最新学习资料) Object Pascal 学习笔记---第11章第1节(混合引用中的错误)

11.1.3 混合引用中的错误 ​ 在使用对象时,你通常应该只使用对象变量或接口变量来访问它们。混合使用这两种方法会破坏对象 Pascal 所提供的引用计数机制,并可能导致极难跟踪的内存错误。在实践中,如果你决定使用接口,你可能应该…

windows驱动开发-内核编程技术汇总(五)

使用安全字符串函数 和应用层不一样的是,windows内核完全使用Unicode字符串,许多支持AsciiC的windowsAPI,是在应用层完成项Unicode的切换的。许多系统安全问题是由缓冲区处理不善和生成的缓冲区溢出引起的。 糟糕的缓冲区处理通常与字符串操…

利用super解决问题

1 问题 在继承问题中,我们可以怎么使用super函数呢? 2 方法 super() 函数是用于调用父类(超类)的一个方法,目的是用来解决多重继承时父类的查找问题。Python中类的初始化都是init(), 所以父类和子类的初始化方式都是init(), 但是如果子类初始…

代码随想录算法训练营第56天| 583. 两个字符串的删除操作*、 72. 编辑距离*

583. 两个字符串的删除操作* 力扣题目链接 代码 示例代码 class Solution { public:int minDistance(string word1, string word2) {vector<vector<int>> dp(word1.size() 1, vector<int>(word2.size() 1));for (int i 0; i < word1.size(); i) dp…

代码随想录算法训练营Day12 | 二叉树理论基础、递归遍历、迭代遍历、统一迭代

今日收获&#xff1a; 二叉树的递归遍历二叉树的迭代遍历&#xff0c;中序的迭代法和前、后序不一样二叉树的统一迭代法主要是用了标记法来实现&#xff08;要处理的节点放入栈之后&#xff0c;紧接着放入一个空指针作为标记&#xff09; 二叉树理论基础篇 题目分类 题目分…

第一篇:刚接触测试你应该知道什么

欢迎你接触软件测试这一行业。 刚接触它时&#xff0c;你肯定或多或少会有疑惑&#xff0c;我该做什么&#xff1f;大家口口相传的软件测试就是 【点点点】 真的是你日常的工作吗&#xff1f; 那么本文我将陪你一起&#xff0c;对我们刚接触到测试这个工作以后&#xff0c;应该…

创建混合索引的原则

创建SQL混合索引的原则如下&#xff1a; 选择合适的列&#xff1a;混合索引应该包含那些经常用于WHERE、JOIN、ORDER BY和GROUP BY子句中的列。选择最常被查询的列&#xff0c;以提高查询的性能。 考虑列的顺序&#xff1a;混合索引的列的顺序应该根据查询的频率和使用的方式进…

x86中汇编伪指令.byte,.short,.int,.long,.word的理解

1[.byte] .byte expressions: 定义一个字节, 并为之分配空间. 2[.short] .short expressions: 定义一个短整型, 并为之分配空间. 3[.int] .int expressions: 定义一个整型,并为之分配空间. 4[.long] .long expressions: 定义一个长整型, 并为之分配空间. 5[.word] .word expres…

产品人生(5):从“敏捷开发”到“四化时间管理法”

人生如产品&#xff0c;产品映人生&#xff0c;借鉴产品思维&#xff0c;快速提升软技能&#xff01; 在互联网的敏捷开发实践中&#xff0c;经常会用到“流程化、模板化、清单化、不断优化”的思想来提升开发的效率和产品质量&#xff0c;并确保团队能够快速响应市场变化。大…

cmake进阶:变量的作用域说明二(从函数作用域方面)

一. 简介 前一篇文章从函数作用域方面学习了 变量的作用域。文章如下&#xff1a; cmake进阶&#xff1a;变量的作用域-CSDN博客 本文继续从函数作用域方面学习了 变量的作用域。 二. 变量的作用域 1. 函数内定义与外部同名的变量 向顶层 CMakeLists.txt添加如下代码&a…

java08基础(值传递和引用传递 类和对象)

目录 一. 值传递和引用传递 1. 值传递 2. 引用传递 二. 面向对象思想 三. 类和对象 1. 类 2. 对象 2.1 使用 2.2 成员变量和局部变量区别 2.3 操作成员方法 2.4 this关键字(初始) 2.5 构造方法 (见java09) 一. 值传递和引用传递 1. 值传递 值传递是指在调用函数时将…