C++ inline 的更进一步理解
文章目录
- 1.概述
- 2.ODR(One Definition Rule)问题
- 3.范例测试代码
- 4.好坏分析
ODR: One Definition Rule,即单一定义规则, C++ 语言中非常重要的一项规则,它确保程序的行为一致性并避免链接时出现冲突。ODR 的核心思想是在整个程序中,每个实体(如变量、函数、类)应该有且仅有一个定义。
在一个程序的所有翻译单元(通常是源文件)中,同一个函数或变量只能有一个定义。如果某个函数或变量在多个翻译单元中有多个定义,那么编译器在链接阶段会报错。这是为了避免在程序中调用某个函数时,编译器不确定应该使用哪一个版本的定义。
inline: 在 C++ 中一般用于建议编译器将函数在调用处进行展开,从而减少函数调用的开销。它是一种编译器优化机制,通常用于小型、简单的函数。
1.概述
现代 C++ 中,inline 的一个重要作用是处理 One Definition Rule (ODR) 问题。
ODR 规定在一个程序中,每个非内联的实体(比如函数或变量)只能有一个定义。然而,如果我们在头文件中定义一个独立函数(而不是声明),并在多个源文件中包含这个头文件,那么编译过程中会产生多个相同的独立函数定义,从而在链接时引发错误。
2.ODR(One Definition Rule)问题
#ifndef _______
#define _______
#include <iostream>void print_message(){std::cout << "Hello,World" << std::endl;
}#endif
多个源码文件包含时:
chVYgFn.o:(.bss+0x0): first defined here
/usr/bin/ld: /tmp/ccMy1ZtX.o: in function `print_message()':
call.cpp:(.text+0x0): multiple definition of `print_message()'; /tmp/cchVYgFn.o:main.cpp:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
解决这个问题,C++11及之前,可以改为 static 函数
C++17及之后,可以如下修改:
#ifndef _______
#define _______
#include <iostream>inline void print_message(){std::cout << "Hello,World" << std::endl;
}#endif
这里 inline 的作用是告诉编译器和链接器:
- 这个独立函数或者变量可以在多个翻译单元中定义。
- 所有这些定义都应该被视为等效的同一个实体(允许多个TU中存在相同定义而不违背ODR,链接时按编译器实现链接某个实现)。
3.范例测试代码
header.h
#ifndef _______
#define _______
#include <iostream>// inline :C++ 17 可以使用 inline,允许多个TU中存在相同定义而不违背ODR,链接时按编译器实现链接某个实现
// static : 也可以使用 static// static/inline
int global_count = 0;// ODR ( One Definition Rule )
// inline 不光是展开,当头文件在多个头文件包含时,
// 没有inline就会存在多个相同函数,造成重定义。
// 但是添加inline,就会保持一份定义。并且与包含一份的 #ifndef / #define 无关。
// inline :C++ 17 可以使用 inline,允许多个TU中存在相同定义而不违背ODR,链接时按编译器实现链接某个实现
// static : 也可以使用 static// static/inline
void print_message(){std::cout << "Hello,World" << std::endl;
}#endif
call.cpp
#include "header.h"
main.cpp
#include "header.h"
#include "header.h"int main(){}
编译:
[root@VM-24-13-centos inline_ODR]# g++ main.cpp call.cpp
/usr/bin/ld: /tmp/ccMo6TBR.o:(.bss+0x0): multiple definition of `global_count'; /tmp/ccEKrehI.o:(.bss+0x0): first defined here
/usr/bin/ld: /tmp/ccMo6TBR.o: in function `print_message()':
call.cpp:(.text+0x0): multiple definition of `print_message()'; /tmp/ccEKrehI.o:main.cpp:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
[root@VM-24-13-centos inline_ODR]#
声明为 static 或 inline 或 static inline 便不再报错
#ifndef _______
#define _______
#include <iostream>static inline
int global_count = 0;static inline
void print_message(){std::cout << "Hello,World" << std::endl;
}#endif
现代C++更趋向于头文件包含实现,这样做就可以避免C++的ODR问题。
4.好坏分析
① static
- static 关键字用于将函数的链接类型设为内部链接。这意味着该函数的作用域仅限于定义它的翻译单元(通常是一个源文件)。
- 使用 static 修饰的函数在整个程序中是本地的,它不会在其他翻译单元中可见。因此,即使在不同的源文件中定义了同名的 static 函数,它们是互相独立的,不会引起冲突。
- static 本身并不会提示编译器进行函数展开。它只影响作用域和链接。
- 如果要 static 函数被展开,可以配合 inline 使用(static inline),这样既保证本地性又增加展开的可能性。
② inline
- inline 函数的链接类型为外部链接(如果没有其他修饰符影响)。它可以在多个翻译单元中使用,但这些翻译单元中的定义必须一致。
- 编译器会将所有使用 inline 关键字定义的同名函数视为同一个函数,并在链接阶段合并这些定义,从而避免 ODR(One Definition Rule) 问题。
- inline 是对编译器的建议,提示它可以在调用处直接展开函数体,从而减少函数调用的开销。但这不是强制的,最终是否展开由编译器决定。
- 在现代编译器中,即使没有 inline,编译器也能根据优化设置自动决定是否展开,因此 inline 更多是解决链接和 ODR 问题的工具。
③ 对比
static:本地可见,多份存在,互不冲突。
inline:被引用时,多份编译单元允许相同存在,解决 ODR 问题,并提示编译器可展开函数。
即,期望应用如下:
- 头文件中定义一个函数并希望它能被多个翻译单元使用,又不想发生链接冲突,就用 inline (C++17起)
- 期望一个函数只在当前翻译单元内可见并且避免与其他文件的同名函数冲突,就用 static
相关文章:
C++ inline 的更进一步理解
文章目录 1.概述2.ODR(One Definition Rule)问题3.范例测试代码4.好坏分析 ODR: One Definition Rule,即单一定义规则, C 语言中非常重要的一项规则,它确保程序的行为一致性并避免链接时出现冲突。ODR 的核心思想是在整个程序中,每…...
海康威视云台相机图像获取
直接上代码: import cv2# 替换为正确的RTSP链接 rtsp_url rtsp://admin:abcd12345192.168.1.64:554/h264/ch1/main/av_stream cap cv2.VideoCapture(rtsp_url)if not cap.isOpened():print("无法打开视频流,检查RTSP URL和凭证") else:whil…...
什么是词嵌入(Word Embedding)
1. 什么是词嵌入(Word Embedding) ⾃然语⾔是⼀套⽤来表达含义的复杂系统。在这套系统中,词是表义的基本单元。顾名思义,词向量是⽤来表⽰词的向量,也可被认为是词的特征向量或表征。把词映射为实数域向量的技术也叫词嵌⼊(word e…...
LSTM时间序列模型实战——预测上证指数走势
LSTM时间序列模型实战——预测上证指数走势 关于作者 作者:小白熊 作者简介:精通python、matlab、c#语言,擅长机器学习,深度学习,机器视觉,目标检测,图像分类,姿态识别,…...
基于 STM32F407 的 SPI Flash下载算法
目录 一、概述二、自制 FLM 文件1、修改使用的芯片2、修改输出算法的名称3、其它设置4、修改配置文件 FlashDev.c5、文件 FlashPrg.c 的实现 三、验证算法 一、概述 本文将介绍如何使用 MDK 创建 STM32F407 的 SPI Flash 下载算法。 其中,SPI Flash 芯片使用的是 W…...
力扣之1355.活动参与者
题目: Sql 测试用例: Create table If Not Exists Friends (id int, name varchar(30), activity varchar(30)); Create table If Not Exists Activities (id int, name varchar(30)); Truncate table Friends; insert into Friends (id, name, acti…...
数据资产治理:构建敏捷与安全的数据管理体系
在当今数字化的盛况下,作为核心资产的数据已经越发受到企业的重视。但是随着公司的逐步壮大,如何分析这些数据以及如何有效治理数据资产,以确保安全性、合规性以及易用性,是企业面临的重大挑战。数聚股份将从多年从业经验深度探讨…...
Nodejs连接Mysql笔记
框架搭建 安装Node.js 首先,确保你已经在系统上安装了Node.js和npm(Node Packaged Modules)。你可以通过以下命令检查是否已经安装:shell 或者 node -v 或者 npm -v 数据库连接代码 1.导入MySQL2库 npm install mysql2 2.在文件…...
Canvas:AI协作的新维度
在人工智能的浪潮中,OpenAI的最新力作Canvas,不仅是一款新工具,它标志着人工智能协作方式的一次革命性飞跃。Canvas为写作和编程提供了一个全新的交互界面,让用户能够与ChatGPT进行更紧密、更直观的协作。 Canvas的…...
【深度学习】— softmax回归、网络架构、softmax 运算、小批量样本的向量化、交叉熵
【深度学习】— softmax回归、网络架构、softmax 运算、小批量样本的向量化、交叉熵 3.4 Softmax 回归3.4.1 分类问题3.4.2 网络架构 3.4.3 全连接层的参数开销3.4.4 softmax 运算3.4.5 小批量样本的向量化3.4.6 损失函数对数似然softmax 的导数 3.4.7 信息论基础熵信息量重新审…...
C# Wpf 图片按照鼠标中心缩放和平移
C# Wpf 图片按照鼠标中心缩放和平移 1、缩放事件 MouseWheel(object sender, MouseWheelEventArgs e)2、平移相关的事件 MouseMove(object sender, MouseEventArgs e) MouseDown(object sender, MouseButtonEventArgs e) MouseUp(object sender, MouseButtonEventArgs e)3、…...
网络安全产品类型
1. 防火墙(Firewall) 功能:防火墙是网络安全的第一道防线,通过检查进出网络的流量来阻止未经授权的访问。它可以基于预定义的安全规则,过滤数据包和阻止恶意通信。 类型: 硬件防火墙:以专用设备…...
【开源风云】从若依系列脚手架汲取编程之道(五)
📕开源风云系列 🍊本系列将从开源名将若依出发,探究优质开源项目脚手架汲取编程之道。 🍉从不分离版本开写到前后端分离版,再到微服务版本,乃至其中好玩的一系列增强Plus操作。 🍈希望你具备如下…...
金融市场的衍生品交易及其风险管理探讨
金融衍生品市场是现代金融体系的重要组成部分,其交易量和复杂性在过去几十年中迅速增长。衍生品,如期权、期货、掉期等,因其灵活性和杠杆效应,广泛应用于风险管理、投机和资产配置等多个领域。本文将探讨金融衍生品交易的关键特点…...
一、创建型(单例模式)
单例模式 概念 单例模式是一种创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点。它控制类的实例化过程,防止外部代码创建新的实例。 应用场景 日志记录:确保只有一个日志记录器,以便于管理和避免重复记…...
毕业设计项目-古典舞在线交流平台的设计与实现(源码/论文)
项目简介 基于springboot实现的,主要功能如下: 技术栈 后端框框:springboot/mybatis 前端框架:html/JavaScript/Css/vue/elementui 运行环境:JDK1.8/MySQL5.7/idea(可选)/Maven3(…...
【秋招笔试】10.09华子秋招(已改编)-三语言题解
🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 大厂实习经历 ✨ 本系列打算持续跟新 春秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 本次的三题全部上线…...
【算法笔记】双指针算法深度剖析
【算法笔记】双指针算法深度剖析 🔥个人主页:大白的编程日记 🔥专栏:算法笔记 文章目录 【算法笔记】双指针算法深度剖析前言一.移动零1.1题目1.2思路分析1.3代码实现 二.复写零2.1题目2.2思路分析2.3代码实现 三.快乐数3.1题目…...
第二十二天|回溯算法| 理论基础,77. 组合(剪枝),216. 组合总和III,17. 电话号码的字母组合
目录 回溯算法理论基础 1.题目分类 2.理论基础 3.回溯法模板 补充一个JAVA基础知识 什么时候用ArrayList什么时候用LinkedList 77. 组合 未剪枝优化 剪枝优化 216. 组合总和III 17. 电话号码的字母组合 回溯法的一个重点理解:细细理解这句话!…...
关闭IDM自动更新
关闭IDM自动更新 1 打开注册表2 找到IDM注册表路径 1 打开注册表 winR regedit 2 找到IDM注册表路径 计算机\HKEY_CURRENT_USER\Software\DownloadManager 双击LstCheck,把数值数据改为0 完成 感谢阅读...
深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
Unity中的transform.up
2025年6月8日,周日下午 在Unity中,transform.up是Transform组件的一个属性,表示游戏对象在世界空间中的“上”方向(Y轴正方向),且会随对象旋转动态变化。以下是关键点解析: 基本定义 transfor…...
在 Visual Studio Code 中使用驭码 CodeRider 提升开发效率:以冒泡排序为例
目录 前言1 插件安装与配置1.1 安装驭码 CodeRider1.2 初始配置建议 2 示例代码:冒泡排序3 驭码 CodeRider 功能详解3.1 功能概览3.2 代码解释功能3.3 自动注释生成3.4 逻辑修改功能3.5 单元测试自动生成3.6 代码优化建议 4 驭码的实际应用建议5 常见问题与解决建议…...
Java并发编程实战 Day 11:并发设计模式
【Java并发编程实战 Day 11】并发设计模式 开篇 这是"Java并发编程实战"系列的第11天,今天我们聚焦于并发设计模式。并发设计模式是解决多线程环境下常见问题的经典解决方案,它们不仅提供了优雅的设计思路,还能显著提升系统的性能…...
如何做好一份技术文档?从规划到实践的完整指南
如何做好一份技术文档?从规划到实践的完整指南 🌟 嗨,我是IRpickstars! 🌌 总有一行代码,能点亮万千星辰。 🔍 在技术的宇宙中,我愿做永不停歇的探索者。 ✨ 用代码丈量世界&…...
GeoServer发布PostgreSQL图层后WFS查询无主键字段
在使用 GeoServer(版本 2.22.2) 发布 PostgreSQL(PostGIS)中的表为地图服务时,常常会遇到一个小问题: WFS 查询中,主键字段(如 id)莫名其妙地消失了! 即使你在…...
当下AI智能硬件方案浅谈
背景: 现在大模型出来以后,打破了常规的机械式的对话,人机对话变得更聪明一点。 对话用到的技术主要是实时音视频,简称为RTC。下游硬件厂商一般都不会去自己开发音视频技术,开发自己的大模型。商用方案多见为字节、百…...
