C++17中的内联变量

      在C++11中:
      (1).声明为constexpr的函数隐式地是内联函数;
      (2).deleted函数隐式地是一个内联函数。
      在内联函数中:
      1.所有函数定义中的函数局部静态对象(function-local static object)在所有翻译单元之间共享(它们都引用一个翻译单元中定义的同一对象)。
      2.所有函数定义中定义的类型在所有翻译单元中也相同。
      inline关键字的最初目的是向优化器指示函数的内联替换优先于函数调用,即不执行函数调用CPU指令将控制权转移到函数体,而是执行函数的副本即函数体在不生成调用的情况下执行。这避免了函数调用(传递参数并检索结果)产生的开销,但可能会导致更大的可执行文件,因为函数的代码必须重复多次。
      由于关键字inline的含义是非绑定的(non-binding),因此编译器可以自由地对任何未标记为内联的函数使用内联替换,并且可以自由地生成对任何标记为内联的函数的函数调用。

      C++17引入了内联变量,即允许在多个文件中定义的变量。内联变量的工作方式与内联函数类似,并且具有相同的要求(编译器必须能够在使用该变量的任何地方看到相同的完整定义)。

      内联说明符(inline specifier)在具有静态存储持续时间(static storage duration)的变量(静态类成员或命名空间范围内的变量)的decl-specifier-seq(declaration specifiers)中使用时,将该变量声明为内联变量。
      声明为constexpr的静态成员变量(但不是命名空间范围内的变量)隐式地是内联变量

      C++的两种链接方式:外部链接(External Linking)和内部链接(Internal Linking)
      1.外部链接:函数或变量可以在其它翻译单元中使用。默认情况下,在C++中定义的函数和全局变量都具有外部链接属性。
      2.内部链接:函数或变量只能在定义它的翻译单元中使用。

      内联函数或内联变量(inline function or inline variable)具有以下属性:
      1.内联函数或内联变量的定义必须在访问它的翻译单元(translation unit,源代码文件如.cpp)中可访问
      2.具有外部链接(external linkage)(例如未声明为静态)的内联函数或内联变量具有以下附加属性:
      (1).程序中可能存在多个内联函数或内联变量的定义,只要每个定义出现在不同的翻译单元中(different translation unit)并且(对于非静态内联函数和内联变量)所有定义都是相同的。例如,内联函数或内联变量可以定义在包含在多个源文件中的头文件中。
      (2).它必须在每个翻译单元中声明为内联。
      (3).每个翻译单元都有相同的地址(same address).

      命名空间范围内的内联const变量默认具有外部链接(与非内联、非易失性、const限定(non-inline non-volatile const-qualified)变量不同)。

      因为函数的关键字inline的含义开始意味着"允许多个定义"而不是"首选内联",所以该含义被扩展到内联变量。在现代C++中,内联已演变为"允许多个定义"的意思

      内联变量消除了将C++代码打包为仅含头文件库的主要障碍(Inline variables eliminate the main obstacle to packaging C++ code as header-only libraries)。

      内联变量在未声明为静态时具有外部链接.
      如果内联变量有多个定义,编译器会在需要时选择其中一个定义.
      与内联函数不同,内联变量可以具有静态存储持续时间(static storage duration)。如果内联变量是在类范围内定义的,则它的行为类似于静态成员变量。此类成员变量可以在类内部初始化
      内联变量在所有翻译单元中具有相同的内存地址。
      C++17允许在不同的翻译单元中对内联变量进行多个定义,并且每个翻译单元将拥有自己的变量副本。
      内联变量默认具有外部链接。如果我们想定义一个具有内部链接的内联变量,我们可以使用静态说明符。
      当我们在全局变量上使用inline关键字时,我们不需要在其他地方将它们定义为"extern"。对于静态成员变量,我们不需要在类外部定义它们
      根据一次定义原则(ODR, One Definition Rule),一个变量或实体的定义只能出现在一个编译单元内----除非该变量或实体被定义为inline的。

      内联变量和thread_local:通过使用thread_local你可以为每个线程创建一个内联变量

      注意:
      (1).如果具有外部链接的内联函数或内联变量在不同的翻译单元中定义不同,则程序格式错误(ill-formed),无需诊断。
      (2).内联说明符不能与块作用域(在另一个函数内)的函数或变量声明一起使用。
      (3).内联说明符无法重新声明已在翻译单元中定义为非内联的函数或非内联的变量。
      (4).隐式生成的(implicitly-generated)成员函数以及在其第一个声明中声明为默认的(defaulted)任何成员函数都是内联的,就像类定义中定义的任何其他函数一样。
      (5).如果在不同的翻译单元中声明内联函数,则每个翻译单元末尾的累积默认参数集必须相同(the accumulated sets of default arguments must be the same at the end of each translation unit)。

      以下为测试代码:

      1. inline.hpp:此头文件会被多个.cpp文件include,若不带inline,会编译不过

class InlineVariable {
public:inline static int var{ 10 }; // 不带inline,则只能在类外初始化;即使在类外初始化,如果被多个cpp文件包含也会error;带inline后,即使被多个cpp文件包含也OKconst char* csdn_addr{ "https://blog.csdn.net/fengbingchun/" };static constexpr int num{ 6 }; // 对于静态成员,constexpr修饰符隐含着inline,等价于: inline static constexpr int num{ 6 };inline static std::string name{ "Messy_Test" }; // 整个程序中只有一个inline static thread_local int count{ 1 }; // 每个线程有一个std::string city{ "BeiJing" }; // 每个实例有一个
};inline InlineVariable inline_variable; // 不带inline,则会报重复定义;带inline后,即使被多个cpp文件包含也OK
inline thread_local InlineVariable inline_variable2; // 每个线程一个对象

      2. inline.cpp:

int test_inline_variable_1()
{std::cout << "var: " << InlineVariable::var << "\n";std::cout << "csdn addr: " << inline_variable.csdn_addr << "\n";std::cout << "num: " << InlineVariable::num << "\n";return 0;
}

      执行结果如下图所示:

      GitHub:https://github.com/fengbingchun/Messy_Test

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

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

相关文章

【c++————————构造函数和析构函数】

【c————————构造函数和析构函数】 欢迎阅读新一期的c模块————构造函数和析构函数 ✒️个人主页&#xff1a;-Joker- &#x1f3f7;️专栏&#xff1a;C &#x1f4dc;代码仓库&#xff1a;c_code &#x1f339;&#x1f339;欢迎大佬们的阅读和三连关注&#xff0c…

软件集成测试

软件集成测试是将各个独立的软件模块组合起来&#xff0c;并测试它们之间的接口和交互是否正常工作的过程。下面是软件集成测试的一般步骤&#xff1a; 确定测试策略&#xff1a;确定集成测试的目标、范围和测试策略。确定要测试的软件模块和它们之间的依赖关系。 设计测试用例…

Dependency Track:智能组件分析平台。

Dependency Track:智能组件分析平台。 ############################# 免责声明:工具本身并无好坏,希望大家以遵守《网络安全法》相关法律为前提来使用该工具,支持研究学习,切勿用于非法犯罪活动,对于恶意使用该工具造成的损失,和本人及开发者无关。 ################…

基于关键点的人脸对齐方法

人脸旋转校正的一般步骤&#xff1a; 1.人脸检测&#xff1a;首先使用人脸检测算法来检测图像中的人脸位置。 2.人脸关键点检测&#xff1a;对于每张检测到的人脸&#xff0c;使用人脸关键点检测算法来检测人脸中的关键点&#xff0c;如眼睛、鼻子、嘴巴等。 &#xff08;项目…

【leetcode100-026】【链表/快慢指针】环形链表II

【题干】 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统…

Linux | 解决问题Ubuntu重启无法进入系统以及网络无法连接【图文详解】

Ubuntu18.04重启无法进入系统&#xff0c;重开后如图 一直在加载系统内核4.15.0-213-generic,无法加载 错误原因 原本的系统是Ubuntu16.04,使用命令升级到Ubuntu18.04版本&#xff0c;升级重启后&#xff0c;远程无法连接&#xff01; 错误解决 第一步&#xff1a;进入GRUB…

AIGC入门系列1:感性的认识扩散模型

1、序言 大家好&#xff0c;欢迎来到AI手工星的频道&#xff0c;我是专注AI领域的手工星。AIGC已经成为AI又一个非常爆火的领域&#xff0c;并且与之前的AI模型不同&#xff0c;AIGC更适合普通人使用&#xff0c;我们不仅可以与chatgpt对话&#xff0c;也能通过绘画模型生成想…

基于SpringBoot的线上学习资源智能推荐系统

文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系🍅 项目介绍 基于SpringBoot的线上学习资源智能推荐系…

使用ASP.NET MiniAPI 调试未匹配请求路径

本文将介绍如何在使用ASP.NET MiniAPI时调试未匹配到的请求路径。我们将详细讨论使用MapFallback方法、中间件等工具来解决此类问题。 1. 引言 ASP.NET MiniAPI是一个轻量级的Web API框架&#xff0c;它可以让我们快速地构建和部署RESTful服务。然而&#xff0c;在开发过程中如…

Hystrix相关面试题及答案

1、什么是Hystrix&#xff0c;它是如何工作的&#xff1f; Hystrix是一个由Netflix开源的库&#xff0c;主要用于在分布式系统中提供延迟和容错功能&#xff0c;通过阻止服务故障的蔓延和提供回退机制来保护系统。它在服务架构中扮演着重要的角色&#xff0c;特别是在微服务架…

PACC:数据中心网络的主动 CNP 生成方案

PACC&#xff1a;数据中心网络的主动 CNP 生成方案 文章目录 PACC&#xff1a;数据中心网络的主动 CNP 生成方案PACC算法CNP数据结构PACC参数仿真结果参考文献 PACC算法 CNP数据结构 PACC参数 仿真结果 PACC Hadoop Load0.2 的情况&#xff1a; PACC Hadoop Load0.4 的情况&a…

go slice源码探索(切片、copy、扩容)和go编译源码分析

文章目录 概要一、数据结构二、初始化2.1、字面量2.2、下标截取2.2.1、截取原理 2.3、make关键字2.3.1、编译时 三、复制3.1、copy源码 四、扩容4.1、append源码 五&#xff1a;切片使用注意事项六&#xff1a;参考 概要 Go语言的切片&#xff08;slice&#xff09;是对数组的…

axios的使用及说明

目录 1.说明 2.直接使用 3.封装使用 4.注意 1.说明 官网&#xff1a;Axios 实例 | Axios中文文档 | Axios中文网 Axios 是一个基于 promise 网络请求库&#xff0c;作用于node.js 和浏览器中。 它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使…

Java超高精度无线定位技术--UWB (超宽带)人员定位系统源码

UWB室内定位技术是一种全新的、与传统通信技术有极大差异的通信新技术。它不需要使用传统通信体制中的载波&#xff0c;而是通过发送和接收具有纳秒或纳秒级以下的极窄脉冲来传输数据&#xff0c;从而具有GHz量级的带宽。 UWB&#xff08;超宽带&#xff09;高精度定位系统是一…

java零拷贝zero copy MappedByteBuffer

目录 调用操作系统的 mmap 未使用 mmap 的文件通过网络传输的过程 使用 mmap 的文件通过网络传输的过程 使用例子 调用操作系统的 sendfile() 在 java 中的具体实现 mmap的优劣 mmap 的不足 mmap 的优点 mmap 的使用场景 对于零拷贝&#xff08;zero copy&#xff09…

C语言实验4:指针

目录 一、实验要求 二、实验原理 1. 指针的基本概念 1.1 指针的定义 1.2 取地址运算符&#xff08;&&#xff09; 1.3 间接引用运算符&#xff08;*&#xff09; 2. 指针的基本操作 2.1 指针的赋值 2.2 空指针 3. 指针和数组 3.1 数组和指针的关系 3.2 指针和数…

【Linux】内核编译 镜像制作

文章目录 一、Ubuntu内核编译1.1 为什么自己编译内核1.2 Ubuntu 内核源码下载1.21 内核的作用1.22 Linux内核与ubuntu内核1.23 Ubuntu内核源码获取 1.3 在Windows系统下编译ubuntu内核1.4 在Linux系统下编译ubuntu内核 二、镜像制作 一、Ubuntu内核编译 1.1 为什么自己编译内核…

用LCD循环右移显示“Welcome to China“

#include<reg51.h> //包含单片机寄存器的头文件 #include<intrins.h> //包含_nop_()函数定义的头文件 sbit RSP2^0; //寄存器选择位&#xff0c;将RS位定义为P2.0引脚 sbit RWP2^1; //读写选择位&#xff0c;将RW位定义为P2.1引脚 sbit EP2^2; //使能…

Debezium日常分享系列之:向 Debezium 连接器发送信号

Debezium日常分享系列之&#xff1a;向 Debezium 连接器发送信号 一、概述二、激活源信号通道三、信令数据集合的结构四、创建信令数据集合五、激活kafka信号通道六、数据格式七、激活JMX信号通道八、自定义信令通道九、Debezium 核心模块依赖项十、部署自定义信令通道十一、信…

【C# 技术】 C# 常用排序方式——自定义数据排序

C# 常用排序方式——自定义数据排序 前言 在最近的项目中经常会对C#中的数据进行排序&#xff0c;对于基本数据类型&#xff0c;其排序方式比较简单&#xff0c;只需要调用内置算法即可实现&#xff0c;但对于自定义数据类型以及自定义排序规则的情况实现起来就比较麻烦&…