深入理解C/C++预处理器指令#pragma once以及与ifndef的比较
#pragma once用法总结
为了防止重复引用造成二义性
在C/C++中,在使用预编译指令#include的时候,为了防止重复引用造成二义性,通常有两种方式
第一种是#ifndef指令防止代码块重复引用,比如说
#ifndef _CODE_BLOCK #define _CODE_BLOCK// code#endif// _CODE_BLOCK第二种就是#pragma once指令,在想要保护的文件开头写入
#pragma once
pragma once 的底层实现
#pragma once是C和C++编程语言中的预处理器指令。预处理器是编译器的一个组成部分,它在编译过程的最初阶段处理源代码。当预处理器遇到#pragma指令时,它会执行特殊的操作,具体取决于紧跟在#pragma后面的文本。在#pragma once的情况下,预处理器将记录包含此指令的文件,并确保在单次编译过程中不会多次包含该文件。具体来说,当预处理器遇到
#pragma once时,它通常会做以下几件事:
预处理器将在内部维护一个列表,记录已经处理过的头文件。每当遇到
#pragma once,预处理器都会检查这个列表。如果头文件已经在列表中,预处理器就会跳过这个头文件,不再处理它。这就防止了同一个头文件在单次编译中被重复包含。
如果头文件还不在列表中,预处理器就会将其添加到列表中,然后正常处理这个头文件。
需要注意的是,
#pragma once并不是标准C++的一部分,尽管大多数现代C++编译器都支持它。因此,其具体行为可能会因编译器而异。在一些情况下,可能会存在问题,比如在文件系统链接(例如软链接或硬链接)或者网络文件系统等复杂场景下,编译器可能无法正确识别文件的唯一性,从而导致#pragma once不能正常工作。在很多情况下,使用传统的头文件保护宏(header guard)是更安全、更标准的做法,例如:
#ifndef HEADER_FILE_H #define HEADER_FILE_H// ... header file content ...#endif // HEADER_FILE_H在这种情况下,预处理器将检查
HEADER_FILE_H是否已经定义。如果已经定义,那么在#ifndef和#endif之间的内容将被忽略。如果尚未定义,预处理器将定义HEADER_FILE_H,并处理在#ifndef和#endif之间的内容。这是一种手动实现#pragma once功能的方法,而且是C++标准支持的。
#pragma once和#ifndef区别
在C/C++编程中,为了防止头文件的重复引用,我们通常使用两种预处理器指令:
#ifndef和#pragma once。这两种指令都有各自的优点和缺点,选择使用哪一种主要取决于你的具体需求和环境。以下是对这两种预处理器指令的比较:
指令 描述 优点 缺点 #ifndef依赖于自定义的宏名,可以保证同一份文件或内容相同的不同文件不会被包含两次。 1. 是C/C++语言的标准支持,兼容性好。 2. 可以针对一个文件中的部分代码。 3. 更加灵活。 1. 如果自定义的宏名重名,可能导致编译器找不到声明的情况。 2. 编译器每次都需要打开头文件才能判定是否有重复定义,可能使得编译大型项目时的时间较长。 #pragma once由编译器提供保证,同一个文件不会被包含多次。 1. 不会出现宏名碰撞引发的问题。 2. 可以提高大型项目的编译速度。 3. 操作简单,效率高。 1. 是非标准的,有些编译器不支持,如GCC 3.4版本之前不支持。 2. 只能针对整个文件。 3. 如果某个头文件有多份拷贝,不能保证它们不被重复包含。 总的来说,
#ifndef和#pragma once都是用于防止头文件的重复引用的有效工具,但它们在实际使用中的效果可能会因项目的具体需求和环境而异。对于#pragma once和#ifndef在C++中的使用,你已经给出了非常详细的解释。这两种预处理器指令都用于防止头文件的重复包含,但它们的工作方式和兼容性有所不同。
编译器差异:#pragma once是一个非标准的预处理器指令,这意味着它可能不被所有的编译器支持。然而,大多数现代编译器(包括GCC,Clang,MSVC等)都支持这个指令。另一方面,#ifndef是一个标准的预处理器指令,因此它在所有的C++编译器中都是被支持的。
文件系统差异:#pragma once的行为可能会受到文件系统的影响。例如,在某些文件系统中,同一文件可能有多个有效的路径,这可能会导致编译器错误地将同一文件视为不同的文件。这是因为#pragma once是通过文件路径来判断文件是否已经被包含的。相比之下,#ifndef不受这种问题的影响,因为它是通过宏名来判断的。
代码可读性:#pragma once指令的语法比#ifndef更简洁,这可能会使代码更易于阅读和理解。然而,这也可能会使得一些复杂的条件编译场景变得更难处理,因为#ifndef提供了更多的灵活性。
性能:在某些情况下,#pragma once可能会比#ifndef更快。这是因为编译器可以立即知道一个文件是否已经被包含,而不需要扫描整个文件。然而,这个性能优势可能并不显著,特别是对于较小的项目。
总的来说,#pragma once和#ifndef都有各自的优点和缺点,选择使用哪一个主要取决于你的具体需求和环境。
相关文章:
深入理解C/C++预处理器指令#pragma once以及与ifndef的比较
#pragma once用法总结 为了防止重复引用造成二义性 在C/C中,在使用预编译指令#include的时候,为了防止重复引用造成二义性,通常有两种方式 第一种是#ifndef指令防止代码块重复引用,比如说 #ifndef _CODE_BLOCK #define _CODE_BLO…...
git 环境配置 + gitee拉取代码
好嘛 配环境的时候 老是忘记这个命令行 干脆自己写一个记录一下 也不用搜了 1.先从git官网下载git 安装 2.然后从gitee拉取代码的时候提示 这是因为换了新电脑没有加入新的公钥啦 哎 所以老是记不住命令行 first : git config --global user.name “Your Name” …...
港联证券|港股拥抱特专科技企业 内资券商“修炼内功”蓄势而为
港股市场新一轮改革举措渐次落地。特别是港交所推出特专科技公司上市机制,吸引符合资格的科技企业申请赴港上市,成为这一轮港股市场改革的“重头戏”。 作为香港资本市场的重要参与者,内资券商立足香港、背靠内地、辐射全球,走出一…...
多项创新技术加持,实现零COGS的Microsoft Editor语法检查器
编者按:Microsoft Editor 是一款人工智能写作辅助工具,其中的语法检查器(grammar checker)功能不仅可以帮助不同水平、领域的用户在写作过程中检查语法错误,还可以对错误进行解释并给出正确的修改建议。神经语法检查器…...
Python编程环境搭建:Windows中如何安装Python
在 Windows 上安装 Python 和安装普通软件一样简单,下载安装包以后猛击“下一步”即可。 Python 安装包下载地址:https://www.python.org/downloads/ 打开该链接,可以看到有两个版本的 Python,分别是 Python 3.x 和 Python 2.x&…...
Sui Builder House首尔站倒计时!
Sui主网上线后的第一场Builder House活动即将在韩国首尔举行,同期将举办首场线下面对面的黑客松。活动历时两天,将为与会者提供独特的学习、交流和娱乐的机会。活动详情请查看:Sui Builder House首尔站|主网上线后首次亮相。 Sui…...
Java设计模式-状态模式
简介 在软件开发领域,设计模式是一组经过验证的、被广泛接受的解决问题的方案。其中之一是状态模式,它提供了一种优雅的方式来管理对象的不同状态。 状态模式是一种行为型设计模式,它允许对象在内部状态发生改变时改变其行为。状态模式将对…...
智慧社区用什么技术开发
智慧社区是指利用信息技术和先进的管理理念,将社区内的各种公共服务进行整合和优化,提高社区居民的生活品质和社区管理的效率。为了实现智慧社区的建设,需要采用多种技术,包括但不限于以下几种: 1.物联网技术…...
多线程 线程池饱和策略
RejectedExecutionHandler(饱和策略):当队列和线程池都满了,说明线程池处于饱和状态,那么必须采取一种策略处理提交的新任务。 这个策略默认情况下是AbortPolicy,表示无法处理新任务时抛出异常。 在JDK 1…...
进程间通信之信号
进程间通信之信号 1. 信号2. 信号由谁产生?3. 有哪些信号4. 信号的安装5. 信号的发送1) 使用kill函数2)使用alarm函数3) 使用raise6.发送多个信号7. 信号集1. 信号 什么是信号? 信号是给程序提供一种可以处理异步事件的方法,它利用软件中断来实现。不能自定义信号,所有信号…...
二分查找三道题
二分查找 两种写法:左闭右闭[left,right]、左闭右开[left,right) 主要有几点不同:1. right是从num.length开始还是从num.length-1开始。2.left<还是<right。3.rightmid还是mid1 左闭右闭写法: public int search(int[] nums, int targ…...
MyBatis 框架
MyBatis 框架 MyBatis 简介搭建 MyBatis 开发环境核心配置文件详解mapper 映射文件(实现增删改查)MyBatis获取参数值的两种方式MyBatis的各种查询功能特殊SQL的执行自定义映射resultMapresultMap 字段和属性的映射多对一映射处理一对多映射处理 动态SQLM…...
【C++】虚表和虚基表到底有哪些区别?
虚表和虚基表 虚表虚基表虚拟继承和虚函数都存在时的对象模型 虚表 我们知道,如果类中声明了的方法是用virtual进行修饰的,则说明当前这个方法要作为虚函数,而虚函数的存储和普通函数的存储是有区别的 当有虚函数声明时,编译器会…...
剑指 Offer 04. 二维数组中的查找解题思路
文章目录 标题解题思路优化 标题 在一个 n * m 的二维数组中,每一行都按照从左到右 非递减 的顺序排序,每一列都按照从上到下 非递减 的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整…...
冯诺依曼体系结构详解
一.冯诺伊曼体系结构的概念: 约翰冯诺依曼(John von Neumann,1903.1.28-1957.2.8),美籍匈牙利数学家,计算机科学家,物理学家。是20世纪最重要的数学家之一,后来被称为计算机之父。 后…...
ISO证书“带标”与“不带标”的区别是什么?
ISO9001质量管理体系认证是企业产品获得“通行绿卡”的最直接最有效的途径。 通过认证在打破贸易壁垒,提高产品知名度,降低生产成本,提高经济效益,维护消费者权益,减少重复审核负担等方面的作用越来越为企业界所共知。…...
RocketMQ 领域模型概述
本文为您介绍 Apache RocketMQ 的领域模型。 Apache RocketMQ 是一款典型的分布式架构下的中间件产品,使用异步通信方式和发布订阅的消息传输模型。通信方式和传输模型的具体说明,请参见下文通信方式介绍和消息传输模型介绍。 Apache RocketMQ 产品具备…...
黄河千年清一回与人类健康
黄河千年清一回奏响一曲曲让人类走进幸福新时代的壮丽凯歌。疫情之后的首届全世界健康产业发展大会 5 月28 日上午 9 时在中国首都北京召开 The Yellow River has played a magnificent song of triumph in the millennium, ushering humanity into a new era of happiness. T…...
Android java层hook------xposed框架的使用
xposed曾经是android平台上最好的java层hook和调试工具,由于已经不再更新,当前支持的android系统版本比较老旧,目前只能支持到android6.0,故已经逐渐落伍,目前android上最广泛使用的hook工具是frida,这是另…...
css奇淫巧计
1.input文本内容替换 -webkit-text-security:通过用形状替换字符,仅影响那些字段不是的typepassword 可选值:none (无),circle (圆圈),disc (圆形),square &a…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...
Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
