当前位置: 首页 > news >正文

#pragma once与条件编译

定义
#pragma once是一个比较常用的C/C++杂注,只要在头文件的最开始加入这条杂注,就能够保证头文件只被编译一次。它是编译器相关的,就是说即使这个编译系统上有效,但在其他编译系统也不一定可以,不过现在基本上已经是每个编译器都有这个杂注了。
#define是C/C++语言中的宏定义,#ifndef,#endif是C/C++语言中的编译。所以在所有支持C++语言的编译器上都是有效的,如果写的程序要跨平台,最好使用这种方式。

比较
#ifndef的方式依赖于宏名字不能冲突,这不光可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件不会被不小心同时包含。当然,缺点就是如果不同头文件的宏名不小心“撞车”,可能就会导致头文件明明存在,编译器却硬说找不到声明的状况
#pragma once则由编译器提供保证:同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。带来的好处是,你不必再费劲想个宏名了,当然也就不会出现宏名碰撞引发的奇怪问题。对应的缺点就是如果某个头文件有多份拷贝,不能保证他们不被重复包含。当然,相比宏名碰撞引发的“找不到声明”的问题,重复包含更容易被发现并修正。
条件编译由语言支持所以移植性好,#pragma once可以避免名字冲突
#pragma once方式产生于#ifndef之后,因此很多人可能甚至没有听说过。目前看来#ifndef更受到推崇。因为#ifndef受语言天生的支持,不受编译器的任何限制;而#pragma once方式却不受一些较老版本的编译器支持,换言之,它的兼容性不够好。也许,再过几年等旧的编译器死绝了,这就不是什么问题了。
我还看到一种用法是把两者放在一起的:
#pragma once
#ifndef __SOMEFILE_H__
#define __SOMEFILE_H__
... ... // 一些声明语句
#endif
看起来似乎是想兼有两者的优点。不过只要使用了#ifndef就不会有宏名冲突的危险,所以混用两种方法似乎不能带来更多的好处,倒是会让一些不熟悉的人感到困惑。

相关文章:

  • 笔试面试经历总结
  • ForFisrtWork--No.1:笔试题初见
  • 说明
  • C++静态类型总结[百度文库文档]
  • ForFisrtWork--No.4:编程题专页
  • ForFisrtWork--No.2:2009软件开发笔试题目
  • ForFisrtWork--No.3:2012合肥笔试题
  • main函数的两个问题
  • C++中的空类,编译器默认可以产生哪些成员函数
  • C/C++内存知识
  • 从错误中得知--关于字符串我以前没注意的东西
  • 从错误中得知--有关malloc自己容易错的地方。
  • C语言学习之内存管理函数malloc()和free()
  • 笔记本电池常识和THINKPAD电源管理器介绍--能设置充电起点和终点
  • C++开发人员必备:86本C++教程电子书下载
  • 9月CHINA-PUB-OPENDAY技术沙龙——IPHONE
  • 分享一款快速APP功能测试工具
  • 【407天】跃迁之路——程序员高效学习方法论探索系列(实验阶段164-2018.03.19)...
  • 10个确保微服务与容器安全的最佳实践
  • C++入门教程(10):for 语句
  • Docker容器管理
  • git 常用命令
  • github从入门到放弃(1)
  • input的行数自动增减
  • PV统计优化设计
  • Vue组件定义
  • 给github项目添加CI badge
  • 前端_面试
  • 前嗅ForeSpider中数据浏览界面介绍
  • 如何解决微信端直接跳WAP端
  • 删除表内多余的重复数据
  • 它承受着该等级不该有的简单, leetcode 564 寻找最近的回文数
  • 学习笔记TF060:图像语音结合,看图说话
  • 一起参Ember.js讨论、问答社区。
  • 关于Android全面屏虚拟导航栏的适配总结
  • #FPGA(基础知识)
  • #git 撤消对文件的更改
  • #NOIP 2014#Day.2 T3 解方程
  • #我与Java虚拟机的故事#连载01:人在JVM,身不由己
  • (1综述)从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练
  • (六) ES6 新特性 —— 迭代器(iterator)
  • (四) 虚拟摄像头vivi体验
  • (一)使用IDEA创建Maven项目和Maven使用入门(配图详解)
  • (转)机器学习的数学基础(1)--Dirichlet分布
  • .Net Core webapi RestFul 统一接口数据返回格式
  • .NET Micro Framework初体验
  • .NET/C# 中你可以在代码中写多个 Main 函数,然后按需要随时切换
  • .Net+SQL Server企业应用性能优化笔记4——精确查找瓶颈
  • .pings勒索病毒的威胁:如何应对.pings勒索病毒的突袭?
  • @angular/cli项目构建--Dynamic.Form
  • @JsonSerialize注解的使用
  • @在php中起什么作用?
  • [20180312]进程管理其中的SQL Server进程占用内存远远大于SQL server内部统计出来的内存...
  • [2023-年度总结]凡是过往,皆为序章
  • [AIGC] Java 和 Kotlin 的区别