C小加
厚德 博学 求真 至善 The bright moon and breeze
posts - 145, comments - 195, trackbacks - 0, articles - 0
C++博客
::
首页
::
新随笔
::
联系
::
聚合
::
管理
#pragma once 与 #ifndef 解析(转)
Posted on 2013-03-18 10:28
C小加
阅读(6848)
评论(2)
编辑
收藏
引用
所属分类:
C++和面向对象
转自:
http://blog.csdn.net/slimfox/article/details/1565950
为了避免同一个文件被include多次,C/C++中有两种方式,一种是#ifndef方式,一种是#pragma once方式。在能够支持这两种方式的编译器上,二者并没有太大的区别,但是两者仍然还是有一些细微的区别。
方式一:
#ifndef __SOMEFILE_H__
#define __SOMEFILE_H__
... ... // 一些声明语句
#endif
方式二:
#pragma once
... ... // 一些声明语句
#ifndef的方式依赖于宏名字不能冲突,这不光可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件不会被不小心同时包含。当然,缺点就是如果不同头文件的宏名不小心“撞车”,可能就会导致头文件明明存在,编译器却硬说找不到声明的状况——这种情况有时非常让人抓狂。
#pragma once则由编译器提供保证:同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。带来的好处是,你不必再费劲想个宏名了,当然也就不会出现宏名碰撞引发的奇怪问题。对应的缺点就是如果某个头文件有多份拷贝,本方法不能保证他们不被重复包含。当然,相比宏名碰撞引发的“找不到声明”的问题,重复包含更容易被发现并修正。
#pragma once方式产生于#ifndef之后,因此很多人可能甚至没有听说过。目前看来#ifndef更受到推崇。因为#ifndef受语言天生的支持,不受编译器的任何限制;而#pragma once方式却不受一些较老版本的编译器支持,换言之,它的兼容性不够好。也许,再过几年等旧的编译器死绝了,这就不是什么问题了。
我还看到一种用法是把两者放在一起的:
#pragma once
#ifndef __SOMEFILE_H__
#define __SOMEFILE_H__
... ... // 一些声明语句
#endif
看起来似乎是想兼有两者的优点。不过只要使用了#ifndef就会有宏名冲突的危险,所以混用两种方法似乎不能带来更多的好处,倒是会让一些不熟悉的人感到困惑。
选择哪种方式,应该在了解两种方式的情况下,视具体情况而定。事实上,只要有一个合理的约定来避开缺点,我认为哪种方式都是可以接受的。而这个已经不是标准或者编译器的责任了,应当由程序员来搞定。
btw:我看到GNU的一些讨论似乎是打算在GCC 3.4(及其以后?)的版本取消对#pragma once的支持。不过我手上GCC 3.4.2和GCC 4.1.1仍然支持#pragma once,甚至没有deprecation warning。VC6及其以后版本亦提供对#pragma once方式的支持。看来这一特性已经稳定下来了。
Feedback
#
re: #pragma once 与 #ifndef 解析(转)
回复
更多评论
2013-03-18 11:30 by
augustheart
gcc已经会报告pragma once的警告了。说什么记不清了,因为自从看到它报后就改用单纯的ifndef方式了,如今都过去一年多了。最开始我也是pragma和ifndef一起用,但是已经记不清为什么一起用了……
这转的文章已经很老了,现在gcc都4.72了。
#
re: #pragma once 与 #ifndef 解析(转)
回复
更多评论
2013-03-20 18:03 by
P
我想知道取消对#pragma once支持原因
刷新评论列表
只有注册用户
登录
后才能发表评论。
【推荐】100%开源!大型工业跨平台软件C++源码提供,建模,组态!
相关文章:
#pragma once 与 #ifndef 解析(转)
C++任意类型转换模板
自己实现的memcpy()代码
学习笔记--空类,虚函数类,虚继承类的空间大小
学习笔记--const的作用
学习笔记--main函数结束后的调用
3种交换变量值的方法
自己实现的strcpy()和strlen()代码
自己实现的atof()和atoi()代码
学习笔记--extern关键字
网站导航:
博客园
IT新闻
BlogJava
博问
Chat2DB
管理
Powered by:
C++博客
Copyright © C小加
日历
<
2013年3月
>
日
一
二
三
四
五
六
24
25
26
27
28
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
公告
ACM小菜奋斗史 QQ:45716108 欢迎交友!
留言簿
(21)
给我留言
查看公开留言
查看私人留言
随笔分类
(143)
C++和面向对象(17)
cocos2dx
JavaScript(1)
Linux(3)
NoSQL(3)
VC++(2)
操作系统(1)
解题报告(83)
模板(5)
设计模式(2)
数据结构和算法(12)
随想人生(7)
网络编程(7)
随笔档案
(145)
2013年7月 (1)
2013年5月 (1)
2013年4月 (2)
2013年3月 (4)
2012年12月 (3)
2012年11月 (1)
2012年9月 (5)
2012年8月 (6)
2012年7月 (1)
2012年6月 (1)
2012年5月 (8)
2012年4月 (6)
2012年3月 (25)
2012年2月 (11)
2012年1月 (12)
2011年12月 (10)
2011年11月 (46)
2011年9月 (1)
2011年4月 (1)
相册
me
各大OJ入口
HDU
POJ
Ural
南阳理工学院(NYOJ)
近期比赛
近期比赛
信息网站
51CTO
ACM/ICPC信息站
CSDN论坛
GameRes
lkylky's blog
OGRE3D
OGRE大牛的bolg
UML软件工程组织
开源社区
木牛
友情链接
v_JULY_v's blog
陈玉's blog
侯飒飒's blog
开开甲's blog
小岳's blog
张云聪's blog
南阳理工学院ACM大牛,目前在百度工作
搜索
积分与排名
积分 - 484819
排名 - 41
最新评论
1. re: 基本数据结构:链表(list)
评论内容较长,点击标题查看
--sanshai
2. re: 一步一步写二叉查找树[未登录]
非常详细 因为有清晰的实例描述一下就懂了 感谢博主
--Lu
3. re: 一步一步写二叉查找树[未登录]
删除操作没有考虑如果删除的是根节点要怎么办吧?
--Andy
4. re: 关于拷贝(复制)构造函数为什么不能用值传递
值传递过程有返回值吗
--奚大坤123
5. re: 一步一步写二叉查找树
调用Deletepri(root,x);进行删除之后,root指向被删除那个位置的节点,而不是原树的根节点?
--胡广
阅读排行榜
1. 基本数据结构:链表(list)(63150)
2. 一步一步写平衡二叉树(AVL树)(42687)
3. C++实现单例模式(17867)
4. 优秀博客推荐:各种数据结构与算法知识入门经典(不断更新)(16175)
5. poj 1005 I Think I Need a Houseboat 解题报告(15778)
评论排行榜
1. 一步一步写平衡二叉树(AVL树)(23)
2. C++实现单例模式(15)
3. 大三下学期计划(15)
4. 标准C++的一些约定(9)
5. 优秀博客推荐:各种数据结构与算法知识入门经典(不断更新)(9)