当前位置: 首页 > 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++教程电子书下载
  • [译] 理解数组在 PHP 内部的实现(给PHP开发者的PHP源码-第四部分)
  • Java到底能干嘛?
  • LeetCode541. Reverse String II -- 按步长反转字符串
  • Material Design
  • Promise初体验
  • Spring Cloud Alibaba迁移指南(一):一行代码从 Hystrix 迁移到 Sentinel
  • 关于extract.autodesk.io的一些说明
  • 简单易用的leetcode开发测试工具(npm)
  • 如何优雅地使用 Sublime Text
  • 一道闭包题引发的思考
  • 一些基于React、Vue、Node.js、MongoDB技术栈的实践项目
  • 关于Kubernetes Dashboard漏洞CVE-2018-18264的修复公告
  • 教程:使用iPhone相机和openCV来完成3D重建(第一部分) ...
  • #我与Java虚拟机的故事#连载02:“小蓝”陪伴的日日夜夜
  • (C语言)求出1,2,5三个数不同个数组合为100的组合个数
  • (Matlab)基于蝙蝠算法实现电力系统经济调度
  • (附源码)计算机毕业设计ssm本地美食推荐平台
  • (接口自动化)Python3操作MySQL数据库
  • (强烈推荐)移动端音视频从零到上手(上)
  • (一)基于IDEA的JAVA基础10
  • (转)我也是一只IT小小鸟
  • .\OBJ\test1.axf: Error: L6230W: Ignoring --entry command. Cannot find argumen 'Reset_Handler'
  • .Net 4.0并行库实用性演练
  • .NET Core SkiaSharp 替代 System.Drawing.Common 的一些用法
  • .net 程序 换成 java,NET程序员如何转行为J2EE之java基础上(9)
  • .NET 发展历程
  • .NET 自定义中间件 判断是否存在 AllowAnonymousAttribute 特性 来判断是否需要身份验证
  • .NET/ASP.NETMVC 深入剖析 Model元数据、HtmlHelper、自定义模板、模板的装饰者模式(二)...
  • /etc/apt/sources.list 和 /etc/apt/sources.list.d
  • ??如何把JavaScript脚本中的参数传到java代码段中
  • []C/C++读取串口接收到的数据程序
  • [2018][note]用于超快偏振开关和动态光束分裂的all-optical有源THz超表——
  • [android] 天气app布局练习
  • [C++] sqlite3_get_table 的使用
  • [C++提高编程](三):STL初识
  • [CF543A]/[CF544C]Writing Code
  • [EFI]ASUS EX-B365M-V5 Gold G5400 CPU电脑 Hackintosh 黑苹果引导文件
  • [IE编程] 了解Urlmon.dll和Wininet.dll
  • [JavaWeb学习] tomcat简介、安装及项目部署
  • [na]wireshark抓包排错-tcp.flags.reset