【c/c++】#pragma once 与 #ifndef 的区别解析

2023-11-07


原文地址:http://blog.csdn.net/hkx1n/article/details/4313303

作用:为了避免同一个文件被include多次,C/C++中有两种方式,一种是#ifndef方式,一种是#pragma once方式。

在能够支持这两种方式的编译器上,二者并没有太大的区别,但是两者仍然还是有一些细微的区别。
    

方式一:
    #ifndef __SOMEFILE_H__
    #define __SOMEFILE_H__
    ... ... // 声明、定义语句
    #endif


    方式二:

     #pragma once
    ... ... // 声明、定义语句


    #ifndef的方式受C/C++语言标准支持。它不光可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件(或者代码片段)不会被不小心同时包含。
    当然,缺点就是如果不同头文件中的宏名不小心“撞车”,可能就会导致你看到头文件明明存在,编译器却硬说找不到声明的状况——这种情况有时非常让人抓狂。
    由于编译器每次都需要打开头文件才能判定是否有重复定义,因此在编译大型项目时,ifndef会使得编译时间相对较长,因此一些编译器逐渐开始支持#pragma once的方式。

    #pragma once一般由编译器提供保证:同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。你无法对一个头文件中的一段代码作pragma once声明,而只能针对文件。
    其好处是,你不必再费劲想个宏名了,当然也就不会出现宏名碰撞引发的奇怪问题。大型项目的编译速度也因此提高了一些。
    对应的缺点就是如果某个头文件有多份拷贝,本方法不能保证他们不被重复包含。当然,相比宏名碰撞引发的“找不到声明”的问题,这种重复包含很容易被发现并修正。

    #pragma once方式产生于#ifndef之后,因此很多人可能甚至没有听说过。目前看来#ifndef更受到推崇。因为#ifndef受C/C++语言标准的支持,不受编译器的任何限制;而#pragma once方式却不受一些较老版本的编译器支持,一些支持了的编译器又打算去掉它,所以它的兼容性可能不够好。一般而言,当程序员听到这样的话,都会选择#ifndef方式,为了努力使得自己的代码“存活”时间更久,通常宁愿降低一些编译性能,这是程序员的个性,当然这是题外话啦。

    还看到一种用法是把两者放在一起的:

    #pragma once
    #ifndef __SOMEFILE_H__
    #define __SOMEFILE_H__
    ... ... // 声明、定义语句
    #endif

    看起来似乎是想兼有两者的优点。不过只要使用了#ifndef就会有宏名冲突的危险,也无法避免不支持#pragma once的编译器报错,所以混用两种方法似乎不能带来更多的好处,倒是会让一些不熟悉的人感到困惑。

    选择哪种方式,应该在了解两种方式的情况下,视具体情况而定。只要有一个合理的约定来避开缺点,我认为哪种方式都是可以接受的。而这个已经不是标准或者编译器的责任了,应当由程序员自己或者小范围内的开发规范来搞定。


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【c/c++】#pragma once 与 #ifndef 的区别解析 的相关文章

  • C# 中的 Culture 相当于 Java 中的 Locale 吗?

    C 使用文化的概念 这在操作上与 Java 中的 Locale 类似吗 或者底层概念是否存在显着差异 从文化而不是语言环境的角度进行工作是一种寻找正确抽象层次的尝试 从以类似方式做事的人群的角度来考虑事物 而不是谈论地理区域和语言 并有点疯
  • 无法对 ContainsGenericParameters 为 true 的类型或方法执行后期绑定操作

    我有一个适用于所有实体的扩展 public static class EntityBaseExtensions public static T Clone
  • 如何指定CMAKE外部项目的编译器?

    我使用ExternalProject Add 包含一个外部项目 我想要的是能够做到 cmake DCMAKE CXX COMPILER
  • ZedGraph 缩放和调整大小

    当我绘制图形 放大和缩小并重新绘制图形时 图形的位置不会改变 我想要做的是 每当重新绘制数据时 视图都会更改以查看所有图形数据 如果您在重绘之前放大或缩小 这似乎会被禁用 Thanks 设置属性 IsZoomOnMouseCenter对于控
  • 对相当大的整数的大集合的操作的快速实现

    描述 我实现了以下类 LabSetInt64 参见下面的代码 这里的目标是尽可能快地操作大量大整数 最多 10M 的值 我的主要要求集中在 至关重要 尽快获取集合的大小 基数 重要 能够非常快速地迭代一组集合 所以 从下面的实现开始 我还有
  • ObservableCollection 上的“Cascade”绑定,包含其他 ObservableCollection

    我有一个项目需要显示合同列表 Class Affaire 每个合约都有一个阶段列表 类别阶段 我使用绑定在 2 个不同的 ListView 中显示它们中的每一个 问题是当我从 ListView 中删除一个 Phase 时 显示 Phases
  • 如何获取任意类型的默认值

    在 C 中我可以写这样的东西 class AnyThing
  • 使用 boost::iterator_facade<>

    我有一个链表结构 struct SomeLinkedList const char bar int lots of interesting stuff in here DWORD foo SomeLinkedList pNext 它是现有
  • CMake - 未定义参考

    我正在尝试将 gtest 包含到我的项目中 问题是我在 GTest 中收到未定义的引用错误 我正在尝试在 Gtest 中测试 Node 类 在节点的构造函数中 我使用类记录器 尽管我已将库记录器添加到 gtest target 中 但我仍然
  • “volatile void function( ... )” 做了什么?

    我见过从语法角度来看 C 函数中 volatile 关键字有多少种用法 https stackoverflow com questions 7643528 how many usage does volatile keyword have
  • 让 GCC/Clang 使用 CMOV

    我有一个简单的标记值联合 这些值可以是int64 ts or doubles 我正在对这些联合进行加法 但需要注意的是 如果两个参数都代表int64 t值 那么结果也应该有一个int64 t value 这是代码 include
  • 使用 MapViewOfFile 有什么限制吗?

    我正在尝试将内存映射文件用作 hFile CreateFile State Path GENERIC READ FILE SHARE READ FILE SHARE WRITE 0 OPEN EXISTING FILE FLAG SEQUE
  • 适用于 Windows 的键值数据库?

    除了 MongoDB 和 Memcached 之外 Windows 上还运行哪些键值存储 我见过的大多数似乎只能在 Linux 上运行 Hypertable Redis Lightcloud 相关链接 是否有经过商业验证的云存储 Key g
  • 使用 for 循环创建链表

    这是我的结构 struct ListItem int data struct ListItem next 假设链表的第一个节点的 data 0 我想编写一个 for 循环来创建大小为 5 的链表 但我不知道如何工作 我尝试了以下方法 int
  • C# Linq 可以做组合数学吗?

    我有这个数据结构 class Product public string Name get set public int Count get set var list new List
  • DLL 中的 XP 风格组合框

    我需要使用 C 和 WIN32 API 无 MFC 在 DLL 中创建 XP 风格的组合框 我设法在 DLL 中创建控件 不是以 XP 风格 我设法在带有清单的 exe 中创建 XP 样式组合框 但它在 DLL 中不起作用 为了让您的 DL
  • 在发送传出请求之前将新的 SoapClient 绑定到特定 IP 地址

    假设应用程序所在的计算机具有 SoapClient 具体来说 我正在使用 Microsoft Web Service3 Messaging SoapClient 它通过发送传出请求并获取 SoapEnvelope 作为回报 完善的流程 与远
  • 没有运算符“<<”与这些操作数匹配[重复]

    这个问题在这里已经有答案了 不知道发生了什么事 我查看了与此问题类似的其他帖子 但到目前为止没有解决方案有帮助 这是带有错误部分注释的代码 在某一时刻 它说 不起作用 而在代码的其余部分中 它说 include
  • 如何使用字符串的值将字符串转换为 wstring?

    我是 C 新手 我有这个问题 我有一个名为 DATA DIR 的字符串 需要将其格式化为 wstring string str DATA DIR std wstring temp L s str Visual Studio 告诉我没有与参数
  • 散列 hash_hmac 时,Convert.ToChar(0) 散列结果与 PHP 中的 chr(0) 不同的字符串

    我在 PHP 中有一个字符串 它被转换为字节数组并进行哈希处理 转换为字节数组的字符串如下所示 G 字符 0 便便 我需要 C 中的等效字节数组 这样我才能得到相同的哈希值 编辑 这是完整的问题 生成的哈希值不同 PHP api secre

随机推荐

  • dp(动态规划)思考

    dp的核心思想是分治策略和表存储 分治策略并非dp所独有 很多算法都运用了把问题拆解为子问题的做法 比如递归 表存储应该是dp比较独有的一种方式 通过存储一些中间结果 可以避免重复计算 从而提升程序运行的速度 def max length
  • 简述3032路pcm帧的结构_基于5G NSA组网结构下用户体验提升研究

    摘要 针对现阶段5G NSA组网结构模式下 开展5G特性研究 以研究5G新一代通信技术与5G相关技术特点为前提 结合实际测试与分析结果 通过对DC双连接 时隙配比以及MASSIVE MIMO差异性3个方面进行分析测试对比 大幅度提升NSA组
  • UnityWebRequest向后端Get数据,后端显示 code 400, message Bad request version 和 HTTPStatus.BAD_REQUEST

    结论 我遇到这个问题是因为UnityWebRequest Get url 中的url是 https localhost port 但是用python flask写的后端服务器url却是 http localhost port 当我把Unit
  • JDBC(二)

    DatabaseMetaData 接口 通过这个接口中的方法可以查看数据库的整体综合信息 DatabaseMetaData 给出的信息描述 DBMS 所提供的事务支持水平 比如 查看驱动程序 数据库 的版本号等 boolean suppor
  • Node.js后端开发 - 进阶篇 #8 express框架之路由模块的封装1

    目录 一 前言 二 路由模块的封装 1 初始化项目 安装express框架 1 npm init y 初始化项目 生成package json文件 2 npm init y 和 npm init 区别 3 安装 express 框架 生成
  • 卸载 SQL Server Management Studio 的操作工具

    我们今天是要和大家一起讨论的是卸载 SQL Server Management Studio 时所要用到的实际操作工具 以及对实现卸载 SQL Server Management Studio 的实际操作步骤的具体描述 以下就是文章的主要内
  • Windows下 Cmake 没有生成makefile文件

    Windows下 Cmake 没有生成makefile文件 不是为了生成解决方案的 针对指令操作 1 主要是因为编译器选择的问题 很有可能选择到了vs的编译器MSVC 了导致生成了解决方案 2 如下操作 使用cmake G Unix Mak
  • 2023年最好用的办公AI工具,让你工作效率提升10倍!

    2023年是AI工具大爆发的一年 在效率办公领域 同样涌现出了很多优秀的AI办公工具 小编亲测了几款 都是宝藏好用的App 以下排名不分先后 一起来看看吧 AI办公工具哪个好 GitMind Notion AI 酷表ChatExcel 通义
  • 计算机老师副业能做什么,教师除了本职工作,还能做哪些副业?

    原标题 教师除了本职工作 还能做哪些副业 本文来源于微信公众号 教师帮 作者 小磊哥 图 互联网 如有转载 请联系并注明原出处 不知老师在学校有没有发现这么一种情况 当你正在为这个月的工资怎么分配而发愁的时候 坐在你身边的同事却春风得意 好
  • 模糊控制器 Matlab 源码程序设计

    模糊控制器 Matlab 源码程序设计 模糊控制是指在不确定 复杂的环境中 通过将自然语言转为数学形式 使用一定的逻辑运算来处理模糊信息 从而实现对系统的控制 在实际应用中 模糊系统已被广泛应用于各种领域 如自动控制 图像处理 数据挖掘等方
  • 软件测试用例编写方法

    边界值分析方法 概念 边界值其实就是一种黑盒测试方法 边界值本质上就是有效等价类和无效等价类的边界 1 边界范围节点 边界值的三个概念 上点 边界值上面的这个点 就是上点 正好等于 内点 有效等价类中的任意一个点 区间范围内的数据 离点 边
  • 改变数据类型

    int 是32 long 是64 numpy改变 pytorch改变 np th list 互换
  • CCF-CSP真题《202305-1 重复局面》思路+python,c++满分题解

    想查看其他题的真题及题解的同学可以前往查看 CCF CSP真题附题解大全 试题编号 202305 1 试题名称 重复局面 时间限制 1 0s 内存限制 512 0MB 问题描述 题目背景 国际象棋在对局时 同一局面连续或间断出现3次或3次以
  • 如何实现概率性事件

    游戏中经常会遇到概率性的问题 比如装备升级的成功率 合成宝石的成功率 洗装备时出现随机属性条数的概率等 这些概率性事件具体是怎么实现的呢 在网上看了一些相关的文章 总结一下 首先需要了解两个函数rand 和srand 下面是百科里面的解释
  • 如何存储Ajax请求的响应值

    如何存储Ajax请求的响应值 一 背景 二 代码部分 三 总结 一 背景 开发者使用Ajax请求网络 获取到了返回的结果 但开发者不想将回调函数写的过于冗长 因此希望将Ajax请求的返回值存储到一个变量中 方便后期取用 二 代码部分 代码部
  • Qt简介以及工程创建

    Qt是一种跨平台应用程序和UI开发框架 只需要一次性开发应用程序 可应用于不同的系统 Qt不是一个严格的前后端 而是一种框架 Qt Creator是一种全新跨平台 Qt IDE集成开发环境 可以单独使用 也可以与Qt库和开发工具组成一套完整
  • Unhandled exception at 0x00291422 in x.exe: 0xC0000005: Access violation writing location 0x37ACCE08

    源码如下 include
  • 线性表顺序存储の介绍、应用 与 实践(第二章: 线性表 )

    一 线性表的介绍 线性表 线性表 linear list 是n个具有相同特性的数据元素的有限序列 线性表是一种在实际中广泛使用的数据结构 常见的线性表 顺序表 链表 栈 队列 字符串 线性表在逻辑上是线性结构 也就说是连续的一条直线 但是在
  • 代码覆盖度工具OpenCppCoverage(cpp)、EclEmma(java)、Coverage(python)使用

    一 OpenCppCoverage cpp OpenCppCoverage是一个运行在windows上的程序 其不是在编译时进行插桩 而是在运行时 因此保证了代码和测试的一致性 参考文档 https github com OpenCppCo
  • 【c/c++】#pragma once 与 #ifndef 的区别解析

    原文地址 http blog csdn net hkx1n article details 4313303 作用 为了避免同一个文件被include多次 C C 中有两种方式 一种是 ifndef方式 一种是 pragma once方式 在